Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PHP ip2long() 为负数 #26

Open
lovecn opened this issue May 29, 2015 · 0 comments
Open

PHP ip2long() 为负数 #26

lovecn opened this issue May 29, 2015 · 0 comments

Comments

@lovecn
Copy link
Owner

lovecn commented May 29, 2015

32 bits ip2long(): -2147483648 ~ 214748364764 
64 bits ip2long(): 0 ~ 4294967295 
ip地址在mysql的存储可以使用varchar(15)或bigint来存储,如果用bigint,php存入时:$ip = ip2long($ip);mysql取出时:SELECT INET_ATON(ip) FROM table ...
php取出时:$ip = long2ip($ip);

//php中可以使用ip2long来转换,具体算法如下:A*256*256*256+B*256*256+C*256+D
function iptolong($ip){
    //先把ip分为四段,$ip1,$ip2,$ip3,$ip4
    list($ip1,$ip2,$ip3,$ip4)=explode(".",$ip);
    //然后第一段乘以256的三次方,第二段乘以256的平方,第三段乘以256
    $ipLong= $ip1*pow(256,3)+$ip2*pow(256,2)+$ip3*256+$ip4;
    return $ipLong;
    //return intval($ipLong);这样会产生负数,因为intval在32和64位操作系统最大值是不同的,32系统: -2147483648 ~ 214748364764 64系统: 0 ~ 9223372036854775807,因此32系统intval('1000000000000')返回 2147483647
}
//ip2long()在32位系统的测试
echo PHP_INT_MAX;//2147483647
ip2long('127.255.255.255'); // 2147483647 = 十进位的最大值 
ip2long('255.255.255.255'); // -1 
ip2long('255.255.255.254'); // -2 
ip2long('192.168.1.2'); // -1062731518 

//ip2long()在64位系统的测试
echo PHP_INT_MAX;//9223372036854775807
ip2long('127.255.255.255'); // 2147483647 = 十进位的最大值 
ip2long('255.255.255.255'); // 4294967295 
ip2long('255.255.255.254'); // 4294967294 
ip2long('192.168.1.2'); // 3232235778 

function iptolong($ip){
    list($ip1,$ip2,$ip3,$ip4)=explode(".",$ip);
    return ($ip1<<24)|($ip2<<16)|($ip3<<8)|($ip4);
}
//相应的long2ip算法:https://my.oschina.net/goal/blog/198049
function longtoip($ip_long) {
    $ip1 = ($ip_long >> 24) & 0xff; // 跟0xff做与运算的目的是取低8位
    $ip2 = ($ip_long >> 16) & 0xff;
    $ip3 = ($ip_long >> 8) & 0xff;
    $ip4 = $ip_long & 0xff;
    return $ip1 . '.' . $ip2 . '.' . $ip3 . '.' . $ip4;
}
function longtoip($ip_long)  {
	    $d = $ip_long%256;
	    $c = (($ip_long-$d)/256)%256;
	    $b = (($ip_long-($c*256)-$d)/(256*256))%256;
	    $a = (($ip_long-($b*256*256)-$c*256-$d)/(256*256*256))%256;
	    return $a.".".$b.".".$c.".".$d;  
}
//javascript相应的long2ip算法:
var ip_long = 2635544666;
var ip1 = (ip_long >> 24) & 0xff;
var ip2 = (ip_long >> 16) & 0xff;
var ip3 = (ip_long >> 8) & 0xff;
var ip4 = ip_long & 0xff;
console.log(ip1 + "." + ip2 + "." + ip3 + "." + ip4);//157.23.56.90
console.log(((157 << 24) | (23 << 16) | (56 << 8) | 90) >>> 0);


$ip = '10.1.1.1';
$ip_long = ip2long($ip);//如果ip无效返回false
echo ip2long('058.99.11.1'); // null
echo ip2long('58.099.11.1'); // null

echo $ip_long;  // 167837953
echo long2ip($ip_long); // 10.1.1.1

//php中将IP转换成整型的函数ip2long在IP比较大的情况下,会变成负数
>>> ip2long('192.168.1.38');
=> -1062731482
//解决方法一:bindec,decbin转换
>>> bindec(decbin(ip2long('192.168.1.38')));
=> 3232235814.0
//解决方法二:使用%u来格式化为无符号整型
$ip = '192.168.1.38';
$ip_long = sprintf('%u',ip2long($ip));
echo $ip_long.PHP_EOL;  // 3232261476 
echo long2ip($ip_long); // 192.168.1.38
//解决方法三:使用iptolong方法

//mysql中相应转换:
>  SELECT INET_ATON('209.207.224.40');
3520061480 
>  SELECT INET_NTOA(3520061480);
'209.207.224.40'



//http://blog.longwin.com.tw/2010/04/php-ip2long-negative-number-fix-2010/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant