检查网段子网是否包含IP地址

2022-08-30 09:33:10

我正在寻找快速/简单的方法,用于将给定的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"; 
    }
}

会是什么样子?cidr_match()

它并不一定很简单,但快速会很好。任何只使用内置/通用函数的东西都是一个奖励(因为我可能会让一个人在pear中向我展示一些可以做到这一点的东西,但我不能依赖pear或安装在我的代码的地方的软件包)。


答案 1

如果仅使用 IPv4:

  • 用于将 IP 和子网范围转换为长整数ip2long()
  • 将 /xx 转换为子网掩码
  • 按位执行“and”(即 ip 和掩码)“,并检查”result = subnet”

像这样的东西应该工作:

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;
}

答案 2

在类似的情况下,我最终使用了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($IP, '10.2.0.0/16')) {
        print "you're in the 10.2 subnet\n";
    }
}

它还处理IPv6。

友情链接: https://packagist.org/packages/symfony/http-foundation


推荐