使用php检查IP是否与IP列表中包含的任何IP相匹配

在$ white数组中,我有一个像这样的IP列表(约10000-12000 ips)

74.125.244.0/22
207.126.144.0/20
77.238.189. 
212.211.149.128/26
194.25.134.8 
194.25.134.9 
194.25.134.12       
174.2.114.12-174.2.115.255
153.2.242.243
153.2.244.12 
153.2.244.50 
153.2.244.63 
153.2.246.30 
153.2.246.31 
153.2.246.35 
153.2.247.30 
153.2.247.31 
153.2.247.32      

因此,数组$ white中的ip列表可以包含这三种格式的ip

153.2.247.32 (simple ip address)
207.126.144.0/20 ( CIDR notation )
174.2.114.12-174.2.115.255 ( Hyphenated ranges )

我的目标是检查另一个数组$ ips(约1000-2000 ips)中是否列出了ips $ white列表。

$ ips列表中的格式仅是简单的ip地址,例如

207.126.144.0
207.126.141.2
201.126.144.5

我正在这样做

foreach ($ips as $check) {
if (in_array($check,$white)){
echo "Ip $check exists";
}
}

但是,检查简单的ip地址只是一件好事,但是我无法检查$ ips中列出的ips是否包含在$ white的连字符范围和CIDR范围中。

我找到了使用ip_in_range.php的解决方案 https://github.com/irazasyed/php-ip-range/blob/master/ip_in_range.php

foreach ($ips as $check) {
    if (in_array($check,$white))
    {
    echo "Ip $check exists";
    }
    else
    {
    foreach( $white as $checkrange )
    {       
if (substr_count($checkrange,'/')>=1 or substr_count($checkrange,'-')>=1 )
{ 
    if (ip_in_range($check,$checkrange)) 
{ 
    echo "Ip $check exists"; 
    break;
}
}

}
}
}

但是它非常慢,因为$ white和$ ips是巨大的列表。 是否存在更快,更有效的解决方案?

jian199 回答:使用php检查IP是否与IP列表中包含的任何IP相匹配

将所有白名单范围预先扩展为一个巨大的单IP地址列表。例如,给定:

mex

您只需处理一次列表即可生成此列表:

mex

然后,将该列表存储在键/值缓存中。可能就像内存中的本机PHP关联数组一样简单,也可能像Redis数据库那样更可靠。然后,您有一个简单的等效性检查是否包含在内。正确实施(例如,通过1.2.3.4 2.3.4.5 3.4.5.6-3.4.5.10 而不是1.2.3.4 2.3.4.5 3.4.5.6 3.4.5.7 3.4.5.8 3.4.5.9 3.4.5.10 实施),无论白名单的大小如何,您都能获得IP查找的O(1)性能。它不可能变得更快。

您不必在每次IP检查中一遍又一遍地进行所有范围处理,而只需在白名单更改时执行一次即可。您基本上是在放弃内存来获取CPU。

,

您可以尝试使用preg_grep

foreach ($ips as $check){

    if(preg_grep("/$check/i",$white))
    {
        echo $input." whitelisted";
    }else{
        echo $input." blacklisted";
    }
{
本文链接:https://www.f2er.com/3158384.html

大家都在问