개발 꿀팁/PHP

php ip2long 음수 발생 원인과 해결 방법

Jammie 2022. 8. 23. 12:30
반응형

php는 ip2long과 long2ip 방법을 제공하여 ip 주소 처리를 한다.

1.ip2long - IPV4의 문자열 인터넷 프로토콜을 숫자로 변환합니다글자 형식

int ip2long ( string $ip_address )

인자: ip_address 표준 형식의 주소입니다.

값 되돌리기: IP 주소 변환 후 숫자나 FALSE를 되돌려줍니다 만약 ip_address가 유효하지 않다면.


2.long2ip - IPV4로 디지털 포맷 변환의 문자열 인터넷 프로토콜

string long2ip ( string $proper_address )

parameter: proper_address 롱패턴의 정확한 주소 표시.

값 되돌리기: 문자열로 인터넷 주소를 되돌려줍니다.


3.사용방법

<?php
$ip = '10.1.1.1';
$ip_long = ip2long($ip);
echo $ip_long.PHP_EOL;  // 167837953
echo long2ip($ip_long); // 10.1.1.1
?>

4.마이너스발생원인 및 처리방법
ip주소가 큰 경우, ip2long은 다음과 같이 음수가 됩니다

<?php
$ip = '192.168.101.100';
$ip_long = ip2long($ip);
echo $ip_long.PHP_EOL;  // -1062705820
echo long2ip($ip_long); // 192.168.101.100
?>

원인 설명:

IPv4는 부호 없는 32비트 주소를 사용하기 때문에 최대 2의 32비트 감산 주소(4294967295)가 1개다.소수점 4개로 나누어진 10진수를 쓴다.
192.168.100.100.100과 같은 A.B.C.D로 표기한다.

IPv4 주소는 10진수마다 부호 없는 바이트입니다. 범위는 0~255입니다. IPv4 주소를 부호 없는 수로 변환하는 것은, 실제로는 10진수마다 대응하는 8자리씩을 붙여 1을 구성하는 것입니다.4바이트의 부호 없는 형식.192.168.100.100,192168은 8위 높은 100, 100은 8위 낮은 수준이다.


C 구현의 예:

#include <stdio.h>

int main(int argc, char** argv)
{
    unsigned int ip_long = (192 << 24) | (168 << 16) | (100 << 8) | 100;
    printf("%u\n", ip_long);
    printf("%d\n", ip_long);

    return 0;
}

fdipzone@ubuntu:~/C$ gcc -o ip2long ip2long.c
fdipzone@ubuntu:~/C$ ./ip2long
3232261220
-1062706076

ip_long이 부호 없는 정형을 선언하더라도 출력할 때 %u를 지정하여 부호 없는 정형으로 포맷할 필요가 있음을 알 수 있다.
192는 127보다 크고(바이너리는 011111), 192(8자리)는 바이너리로 표현하면 최상위 1이 되기 때문이다.이 4바이트 정형의 최고 비트는 1이다.
ip_long은 부호 없는 정형으로 정의되지만 printf 방법은 성명을 무시한다.그래서 %u 포맷으로 해야 돼요.出. 최상위 0이면 %d을(를) 사용하면 됩니다.


또 다른 예:
ip:112.24.55.99

#include <stdio.h>

int main(int argc, char** argv)
{
    unsigned int ip_long = (112 << 24) | (24 << 16) | (55 << 8) | 99;
    printf("%u\n", ip_long);
    printf("%d\n", ip_long);

    return 0;
}
fdipzone@ubuntu:~/C$ gcc -o ip2long ip2long.c
fdipzone@ubuntu:~/C$ ./ip2long
1880635235
1880635235

해결 방법:

%u를 사용하여 부호 없는 형식으로 출력합니다

<?php
$ip = '192.168.101.100';
$ip_long = sprintf('%u',ip2long($ip));
echo $ip_long.PHP_EOL;  // 3232261476 
echo long2ip($ip_long); // 192.168.101.100
?>

 

반응형