<?php
//判断内网的函数
//Author :lijunjie
function is_internal_ip($ip) {
$ip = ip2long($ip);
$a = ip2long('10.0.0.0'); //A类网的预留ip
$b = ip2long('172.16.0.0'); //B类网的预留ip
$c = ip2long('192.168.0.0'); //C类网的预留ip
return ($ip & $a) === $a || ($ip & $b) === $b || ($ip & $c) === $c);
}
?>
上面写错了,应该利用掩码的概念来处理这个问题。
<?php
function is_internal_ip($ip) {
$ip = ip2long($ip);
$net_a = ip2long('10.255.255.255') >> 24; //A类网预留ip的网络地址
$net_b = ip2long('172.31.255.255') >> 20; //B类网预留ip的网络地址
$net_c = ip2long('192.168.255.255') >> 16; //C类网预留ip的网络地址
return $ip >> 24 === $net_a || $ip >> 20 === $net_b || $ip >> 16 === $net_c;
}
?>
注:
ip地址中预留的内网ip地址如下:
A类: 10.0.0.0 ~ 10.255.255.255
B类: 172.16.0.0 ~ 172.31.255.255
C类: 192.168.0.0 ~ 192.168.255.255
二进制表示:
A类: 00001010 00000000 00000000 00000000 ~ 00001010 11111111 11111111 11111111
B类: 10101100 00010000 00000000 00000000 ~ 10101100 00011111 11111111 11111111
C类: 11000000 10101000 00000000 00000000 ~ 11000000 10101000 11111111 11111111
十进制的表示基本看不出规律,写成二进制就有规律了,注意红色的部分
下面看另外一个判断内网ip的写法:
<?php
function _isPrivate($ip) {
$i = explode('.', $ip);
if ($i[0] == 10) return true;
if ($i[0] == 172 && $i[1] > 15 && $i[1] < 32) return true;
if ($i[0] == 192 && $i[1] == 168) return true;
return false;
}
?>
判断ip是否属于某个子网的函数:
<?php
/**
* isValidateIP
* 检查ip是否属于某个子网
* @param subnet:子网;如: 10.10.10/24 或 10.10.10.0/24 都是一样的
* @return true | false
*/
function isValidateIP($subnet,$ip)
{
$arr = explode('/',trim($subnet));
if(count($arr) == 1) //支持单个ip的写法
{
return $ip == $arr[0];
}
$long_ip = ip2long(trim($ip));
$net = ip2long($arr[0]);
$hosts = pow(2,32-$arr[1]) - 1; //主机部分最大值
$host = $net ^ $long_ip; //客户端ip的主机部分
return $host >= 0 && $host <= $hosts;
}
?>
评论