php提供了ip2long與long2ip方法對ip地址處理。php
int ip2long ( string $ip_address )1
參數: ip_address 一個標準格式的地址。ubuntu
返回值: 返回IP地址轉換後的數字 或 FALSE 若是 ip_address 是無效的。
spa
string long2ip ( string $proper_address )1
參數: proper_address 長整型的正確地址表示。.net
返回值: 返回互聯網地址做爲字符串。
code
<?php$ip = '10.1.1.1';$ip_long = ip2long($ip);echo $ip_long.PHP_EOL; // 167837953echo long2ip($ip_long); // 10.1.1.1?>123456
當ip地址比較大時,ip2long會出現負數:orm
<?php$ip = '192.168.101.100';$ip_long = ip2long($ip);echo $ip_long.PHP_EOL; // -1062705820echo long2ip($ip_long); // 192.168.101.100?>123456
緣由說明:blog
IPv4使用無符號32位地址,所以最多有2的32次方減1(4294967295)個地址。書寫用4個小數點分開的10進制數。
記爲A.B.C.D,例如:192.168.100.100。ip
IPv4地址每一個10進制數都是無符號的字節,範圍在0~255,將IPv4地址轉爲無符號數,其實就是將每一個10進制數放在對應的8位上,組成一個4字節的無符號整型。192.168.100.100,192,168在高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$ ./ip2long3232261220-1062706076123456789101112131415
能夠看到,即便ip_long聲明是無符號整型,輸出時依然須要指明%u來格式化輸出爲無符號整型。
由於192大於127(二進制爲01111111),192(8位)用二進制表示,最高位必然是1。致使這個4字節整型的最高位爲1。
雖然ip_long定義爲無符號整型,但printf方法是不理會聲明的。因此須要使用%u格式化來輸出。若是最高位是0,則使用%d便可。
另外一個例子:
ip:112.24.55.99get
#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$ ./ip2long188063523518806352351234567891011121314
解決方法:
輸出時用%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?>123456