Intereting Posts
Внедрить карту в javascript, которая поддерживает методы объектов как отображаемые функции? Кто должен обрабатывать условия в сложных запросах, карту данных или уровне обслуживания? PHP завиток, возвращающий странные символы отображать данные из базы данных SQL в таблицу php / html Сгенерировать один и тот же тип формы на одной странице несколько раз Symfony2 PHP – сортировка элементов массива на основе элементов другого массива :) Код парсера с открытым исходным кодом для разметки Mediawiki лучший способ определить количество SMS, необходимых для отправки текста Как использовать API Google SpreadSheets для подачи данных в приложение? Поиск количества дней между двумя датами Crypto-Js различный вывод из mcrypt. После считывания данных для шифрования Как переписать URL-адрес в php, используя файл htaccess. какое изменение в php-коде Перемещение стиля с PHP на голову Symfony подключает идентификатор пользователя от объекта Laravel 4: Как применить условие WHERE ко всем запросам класса Eloquent?

Определите, существует ли данный IP-адрес в CIDR или нет

Я получаю IP-адрес пользователя, используя $ _SERVER ['REMOTE_ADDR'], который пытается посетить мой сайт. У меня есть разные коробки с разными IDS и разными записями CIDR в моей базе данных для каждого окна. Я хочу проверить, существует ли IP-адрес пользователя в любом из CIDR или нет для определенного поля. Если он существует, тогда ему разрешено вводить иначе. допустим, что IP-адрес пользователя

127.0.0.1 

предположим, что записи CIDR для блока 12

 192.168.1.20/27 192.168.0.10/32 

Записи CIDR хранятся в столбце базы данных

если он приходит с IP-адресом, входящим в этот диапазон, тогда ему должно быть разрешено войти на сайт, иначе нет. Я хочу проверить его ip против каждой записи CIDR.

Любые идеи, пожалуйста?

благодаря

Solutions Collecting From Web of "Определите, существует ли данный IP-адрес в CIDR или нет"

Хорошо, попробуйте выполнить следующие 5 простых шагов …

1. Храните свои CIDR в массиве (читайте их из базы данных, предположите, что знаете, как это получить)

 $cidrs = array( '192.168.1.20/27', '192.168.0.10/32' ); 

2. Получить IP-адрес пользователя (удаленный адрес)

 $user_ip = $_SERVER['REMOTE_ADDR']; 

3. Добавьте эту функцию

 function IPvsCIDR($user_ip, $cidr) { $parts = explode('/', $cidr); $ipc = explode('.', $parts[0]); foreach ($ipc as &$v) $v = str_pad(decbin($v), 8, '0', STR_PAD_LEFT); $ipc = substr(join('', $ipc), 0, $parts[1]); $ipu = explode('.', $user_ip); foreach ($ipu as &$v) $v = str_pad(decbin($v), 8, '0', STR_PAD_LEFT); $ipu = substr(join('', $ipu), 0, $parts[1]); return $ipu == $ipc; } 

4. Сравните IP-адрес пользователя с $ cidrs

 $validaddr = false; foreach ($cidrs as $addr) if (IPvsCIDR($user_ip, $addr)) { $validaddr = true; break; } 

5. Решите, что делать с пользователем

 if ($validaddr) { echo "CORRECT IP ADDRESS"; } else { echo "INCORRECT IP ADDRESS"; } 

Это оно!

как эта функция работает. Он преобразует адресную часть CIDR (xxxx) в двоичную строку и принимает первые N цифр. Затем он выполняет ту же работу с IP-адресом пользователя и проверяет соответствие значений.

Пример 2 (полная работа из функции)

 function testUserIP($user_ip, $cidrs) { $ipu = explode('.', $user_ip); foreach ($ipu as &$v) $v = str_pad(decbin($v), 8, '0', STR_PAD_LEFT); $ipu = join('', $ipu); $res = false; foreach ($cidrs as $cidr) { $parts = explode('/', $cidr); $ipc = explode('.', $parts[0]); foreach ($ipc as &$v) $v = str_pad(decbin($v), 8, '0', STR_PAD_LEFT); $ipc = substr(join('', $ipc), 0, $parts[1]); $ipux = substr($ipu, 0, $parts[1]); $res = ($ipc === $ipux); if ($res) break; } return $res; } 

Применение:

 $user_ip = $_SERVER['REMOTE_ADDR']; $cidrs = array('192.168.1.20/27', '192.168.0.10/32'); if (testUserIP($user_ip, $cidrs)) { // user ip is ok } else { // access denied } 

Я использовал эту функцию некоторое время:

 <?php /** * Returns TRUE if given IPv4 address belongs to given network, FALSE otherwhise * * @param string $str_ip IP address in '127.0.0.1' format * @param string $str_range Network and mask as '127.0.0.0/8', '127.0.0.0/255.0.0.0' or '127.0.0.1' * @return bool * * @version v2011-08-30 */ function ip_belongs_to_network($str_ip, $str_range){ // Extract mask list($str_network, $str_mask) = array_pad(explode('/', $str_range), 2, NULL); if( is_null($str_mask) ){ // No mask specified: range is a single IP address $mask = 0xFFFFFFFF; }elseif( (int)$str_mask==$str_mask ){ // Mask is an integer: it's a bit count $mask = 0xFFFFFFFF << (32 - (int)$str_mask); }else{ // Mask is in xxxx format $mask = ip2long($str_mask); } $ip = ip2long($str_ip); $network = ip2long($str_network); $lower = $network & $mask; $upper = $network | (~$mask & 0xFFFFFFFF); return $ip>=$lower && $ip<=$upper; } 

Обновить:

Фактически все записи CIDR находятся в базе данных в моем случае. Как я могу проверить IP-адрес с помощью всех записей CIDR, может ли цикл foreach работать?

Это зависит от того, сколько у вас записей. Петля PHP отлично подходит для нескольких диапазонов, но из 50 из них будет запускать 50 SQL-запросов! В этом случае вам, вероятно, следует переключиться на подход к базе данных. Например, вы можете хранить диапазоны в двух столбцах (более низкий IP-адрес и верхний IP-адрес). Таким образом, все, что вам нужно сделать, будет следующим:

 $sql = 'SELECT COUNT(1) AS belongs_to_at_least_one_range FROM ranges WHERE :remote_address BETWEEN lower_address AND upper_address LIMIT 1'; $params = array( 'remote_address' => ip2long($_SERVER['REMOTE_ADDR']), ); 

(Или выберите все соответствия, если вам это нужно.)

Вы можете объяснить эту строку list($str_network, $str_mask) = array_pad(explode('/', $str_range), 2, NULL); кодов list($str_network, $str_mask) = array_pad(explode('/', $str_range), 2, NULL);

 explode('/', $str_range) // Split the string at `/` characters array_pad(explode('/', $str_range), 2, NULL); // Fill with NULLs if we have less than 2 items list($str_network, $str_mask) = // Store first part in `$str_network` and second part in `$str_mask`