function ip_address_to_number($IPaddress) {
if(!$IPaddress) {
return false;
} else {
$ips = split('\.',$IPaddress);
return($ips[3] + $ips[2]*256 + $ips[1]*65536 + $ips[0]*16777216);
}
}
该函数执行与php捆绑函数ip2long相同的代码。但是,当我打印这2个值时,我得到2个不同的回报。为什么? (我在wamp环境中使用php 5.2.10。)
ip2long('200.117.248.17'); //returns **-931792879**
ip_address_to_number('200.117.248.17'); // returns **3363174417**
应用并继续在这里: Showing my country based on my IP, mysql optimized
答案 0 :(得分:32)
答案 1 :(得分:9)
glopes@nebm:~$ php -r "printf('%u', -931792879);" 3363174417
你去吧。我的猜测是你在一个32位整数的系统上,你的ip_address_to_number
实际上正在返回一个浮点数。
你会看到,使用32位整数,你的最大正整数是(2^31) - 1 = 2 147 483 647
,所以整数回绕。
如果您想模仿PHP函数的行为,请执行:
function ip_address_to_number($IPaddress) {
if(!$IPaddress) {
return false;
} else {
$ips = split('\.',$IPaddress);
return($ips[3] | $ips[2] << 8 | $ips[1] << 16 | $ips[0] << 24);
}
}
(顺便说一下,split
已被弃用)
答案 2 :(得分:6)
$ips[3] = 17
+ $ips[2] * 256 = 248 * 256 = 63488
+ $ips[1] * 65536 = 117 * 65536 = 7667712
+ $ips[0] * 16777216 = 200 * 16777216 = 3355443200
= 3363174417
PHP max整数值(32位)是2147483647,其是&lt; 3363174417
从ip2long()PHP手册页引用
注意:因为PHP的整数类型是 签名,许多IP地址将 导致负整数,你需要 使用sprintf()的“%u”格式化程序 或printf()来获取字符串 无符号IP的表示 地址。
答案 3 :(得分:1)
您可以使用 -
// IP Address to Number
function inet_aton($ip)
{
$ip = trim($ip);
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) return 0;
return sprintf("%u", ip2long($ip));
}
// Number to IP Address
function inet_ntoa($num)
{
$num = trim($num);
if ($num == "0") return "0.0.0.0";
return long2ip(-(4294967295 - ($num - 1)));
}
答案 4 :(得分:0)
<?php
function _ip2long($input)
{
$r = null;
if (is_string($input))
{
$_input = trim($input);
if (filter_var($_input, FILTER_VALIDATE_IP))
{
$PRE_r = explode('.', $_input);
$r = ($PRE_r[0] * pow(256, 3)) + ($PRE_r[1] * pow(256, 2)) + ($PRE_r[2] * 256) + ($PRE_r[0]);
} else
{
$r = false;
}
} else
{
$r = false;
}
return ($r);
}
$out = _ip2long('127.0.0.1');
if (false === $out)
{
print('Invalid IP');
} else
{
print($out);
}
?>
答案 5 :(得分:0)
是否进行了一些性能测试来比较运行ip2long
到sprintf
与数组爆炸,然后是时间或按位移位:
<?php
header ('Content-Type: text/plain');
function ip_range($start, $count) {
$start = ip2long($start);
return array_map('long2ip', range($start, $start + $count) );
}
$iterations = 500000;
$results = array();
$ips = ip_range('192.168.1.1', $iterations);
$time = microtime(true);
foreach ($ips as $ip) {
$result = sprintf('%u', ip2long($ip));
}
$time = microtime(true) - $time;
$results['ip2long'] = array ('total' => $time, 'cycles' => $iterations, 'average' => ($time / $iterations) . 's', 'speed' => ($iterations/$time) . ' hashes per second.' );
$time = microtime(true);
foreach ($ips as $ip) {
$aIp = explode('.', $ip);
if (count($aIp) == 4) {
$result = /*sprintf('%u',*/ $aIp[0]*16777216 + $aIp[1]*65536 + $aIp[2]*256 + $aIp[3] /*)*/;
}
else
{
$result = false;
}
}
$time = microtime(true) - $time;
$results['explode multiple'] = array ('total' => $time, 'cycles' => $iterations, 'average' => ($time / $iterations) . 's', 'speed' => ($iterations/$time) . ' hashes per second.' );
$time = microtime(true);
foreach ($ips as $ip) {
$aIp = explode('.', $ip);
if (count($aIp) == 4) {
$result = /*sprintf('%u',*/ $aIp[3] | $aIp[2] << 8 | $aIp[1] << 16 | $aIp[0] << 24 /*)*/;
}
else
{
$result = false;
}
}
$time = microtime(true) - $time;
$results['explode bitwise'] = array ('total' => $time, 'cycles' => $iterations, 'average' => ($time / $iterations) . 's', 'speed' => ($iterations/$time) . ' hashes per second.' );
die(var_dump($results));
结果如下:
array(3) {
["ip2long"]=>
array(4) {
["total"]=>
float(0.92530012130737)
["cycles"]=>
int(500000)
["average"]=>
string(19) "1.8506002426147E-6s"
["speed"]=>
string(34) "540365.21609177 hashes per second."
}
["explode multiple"]=>
array(4) {
["total"]=>
float(0.91870212554932)
["cycles"]=>
int(500000)
["average"]=>
string(19) "1.8374042510986E-6s"
["speed"]=>
string(34) "544246.04678153 hashes per second."
}
["explode bitwise"]=>
array(4) {
["total"]=>
float(0.9184091091156)
["cycles"]=>
int(500000)
["average"]=>
string(19) "1.8368182182312E-6s"
["speed"]=>
string(34) "544419.68730197 hashes per second."
}
}
在sprintf
中按位和乘法时,它们比ip2long
慢,但由于不需要它,它们会更快。