大家知道,为了内网使用,ip地址中分被从A类、B类、C类网划分出一些地址供内网使用,后来工作中有个需求,需要判断ip是否是预留的ip地址,我也很懒,知道很有规律,但是就是不想自己写,就想到网上找个,但是翻破了互联网都没找见,一气之下就直接写了一个,同时也为互联网的更加强大添砖加瓦,以下是本人写的,仅供参考,如有不足之处(我相信肯定有的),烦请留言指教!
<?php//判断内网的函数
//Author :lijunjie
//Mail :lijunjie1982@yahoo.com.cn
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;
}
?>