php ip2long 出現負數緣由及解決方法

php提供了ip2long與long2ip方法對ip地址處理。php

1.ip2long — 將一個IPV4的字符串互聯網協議轉換成數字格式

int ip2long ( string $ip_address )1

參數: ip_address 一個標準格式的地址。ubuntu

返回值: 返回IP地址轉換後的數字 或 FALSE 若是 ip_address 是無效的。 

spa

2.long2ip — 將數字格式轉換成一個IPV4的字符串互聯網協議

string long2ip ( string $proper_address )1

參數: proper_address 長整型的正確地址表示。.net

返回值: 返回互聯網地址做爲字符串。 

code

3.使用方法

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


4.出現負數緣由及處理方法

當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
相關文章
相關標籤/搜索