проверьте, соответствует ли ip любому ip, содержащемуся в списке ip, используя php - PullRequest
0 голосов
/ 05 ноября 2019

в массиве $ 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      

Итак, список ip в массиве $ white может содержать ip (s) в этих трех форматах

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, перечисленные в другом массиве, $ ips (около 1000-2000 ips), в белом списке.

Формат в $ 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содержатся в диапазонах переносов и CIDR в $ white.

Я нашел решение, используя 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огромные списки. Существует ли более быстрое и эффективное решение?

Ответы [ 2 ]

2 голосов
/ 05 ноября 2019

Предварительно разверните все диапазоны белого списка в один гигантский список отдельных IP-адресов. Например, с учетом:

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

Затем сохраните этот список в кэше ключ / значение. Это может быть что-то простое, например, ассоциативный массив PHP, хранящийся в памяти, или нечто более надежное, например, база данных Redis. Тогда у вас есть простая проверка эквивалентности для включения. Реализованный правильно (например, через array_key_exists() вместо in_array()), вы получите производительность O (1) для поиска IP, независимо от размера белого списка. Это не может быть быстрее.

Вместо того, чтобы выполнять всю обработку диапазона снова и снова на каждой отдельной проверке IP, вы делаете это только один раз, когда меняется белый список. В основном вы отказываетесь от памяти, чтобы получить процессор.

0 голосов
/ 05 ноября 2019

Вы можете попробовать с preg_grep :

foreach ($ips as $check){

    if(preg_grep("/$check/i",$white))
    {
        echo $input." whitelisted";
    }else{
        echo $input." blacklisted";
    }
{
...