我正在寻找快速/简单的方法来匹配给定的IP4点分四核IP到CIDR表示法掩码.
我有一堆IP,我需要看看它们是否匹配一系列IP.
例:
$ips = array('10.2.1.100', '10.2.1.101', '10.5.1.100', '1.2.3.4');
foreach ($ips as $IP) {
if (cidr_match($IP, '10.2.0.0/16') == true) {
print "you're in the 10.2 subnet\n";
}
}
Run Code Online (Sandbox Code Playgroud)
会是什么cidr_match()模样?
它并不一定非常简单,但快速会很好.任何只使用内置/通用功能的东西都是奖励(因为我很可能会让一个人向我展示梨的东西,但是我不能依赖梨或者我的代码所在的地方安装的包部署).
Aln*_*tak 73
如果仅使用IPv4:
ip2long()将IP和子网范围转换为长整数这样的事情应该有效:
function cidr_match($ip, $range)
{
list ($subnet, $bits) = explode('/', $range);
if ($bits === null) {
$bits = 32;
}
$ip = ip2long($ip);
$subnet = ip2long($subnet);
$mask = -1 << (32 - $bits);
$subnet &= $mask; # nb: in case the supplied subnet wasn't correctly aligned
return ($ip & $mask) == $subnet;
}
Run Code Online (Sandbox Code Playgroud)
Dáv*_*zki 47
在类似的情况下,我最终使用symfony/http-foundation.
使用此包时,您的代码如下所示:
$ips = array('10.2.1.100', '10.2.1.101', '10.5.1.100', '1.2.3.4');
foreach($ips as $IP) {
if (\Symfony\Component\HttpFoundation\IpUtils::checkIp($_SERVER['REMOTE_ADDR'], '10.2.0.0/16')) {
print "you're in the 10.2 subnet\n";
}
}
Run Code Online (Sandbox Code Playgroud)
它还处理IPv6.
链接:https://packagist.org/packages/symfony/http-foundation
Sam*_*son 44
我发现许多这些方法在PHP 5.2之后破裂.但是,以下解决方案适用于5.2及更高版本:
function cidr_match($ip, $cidr)
{
list($subnet, $mask) = explode('/', $cidr);
if ((ip2long($ip) & ~((1 << (32 - $mask)) - 1) ) == ip2long($subnet))
{
return true;
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
示例结果
cidr_match("1.2.3.4", "0.0.0.0/0"): true
cidr_match("127.0.0.1", "127.0.0.1/32"): true
cidr_match("127.0.0.1", "127.0.0.2/32"): false
来源http://www.php.net/manual/en/function.ip2long.php#82397.
一些功能改变了:
function cidr_match($ip, $range)
{
list ($subnet, $bits) = explode('/', $range);
$ip = ip2long($ip);
$subnet = ip2long($subnet);
$mask = -1 << (32 - $bits);
$subnet &= $mask;
return ($ip & $mask) == $subnet;
}
Run Code Online (Sandbox Code Playgroud)