Скрипт проверки принадлежности IP к диапазонам российских сетей

Kuzmich_spb

Новичок
Скрипт проверки принадлежности IP к диапазонам российских сетей

Нужно проверить принадлежит ли ip юзера который открывает страничку к диапазонам http://www.parkline.ru/rusnets/russia.txt.
Я предлагаю пометить список сетей в базу Mysql.

Но виде лучше его (спикок сетей) хранить в базе?
И как делать поиск, таки образом чтобы производительность была максимальной?
 

Kuzmich_spb

Новичок
Автор оригинала: baldman
можно прикрутить GeoIp модуль к апачу и сличать Ip
К сожалению не получится т.к сервер хостера и они не дадут ни чего прикручивать к апачу.

Я сейчас пробую самый тупой способ записать все ип в базу в десятичном виде. Преобразуя их функцией ip2int с http://php.spb.ru/php/ip.html.

Самому интересно сколько таблица будет весить.
 

magic

lancer
Весить будет немного. Таблица с IP адресами всех стран занимает около 750 Кб.
 

Kuzmich_spb

Новичок
magic 750 Кб? это немного.


Вот если бы все сети были не меньше *.*.*.0/24 (*.*.*.0 - *.*.*.255)
то можно было преобразовать все диапазоны к /24.
Потом записать их в базу как *.*.*.0.

А IP для проверки тоже преобразовывать к виду *.*.*.0.
Если IP 194.74.1.125 он станет 194.74.1.0 и в базе искать сеть 194.74.1.0/24, которая записана как 194.74.1.0. т.е просто WHERE range = 194.74.1.0

НО есть сети 62.117.127.37/32 ; 194.85.252.48/28. Для которых такай способ не подходит.
Но с другой стороны таких мало и ими можно принебречь.
 

magic

lancer
Что-то Вы, батенька, сами себя обхитрили. Таблица состоит из двух полей - start & end:
33996344 33996351
50331648 68257567
68257568 68257599
68257600 68259583
68259584 68259599
 

Kuzmich_spb

Новичок
magic спасибо


запрос будет такой SELECT id from ip_table WHERE start_ip<$check_ip AND $check_ip<$end_ip

если находит один ряд - тест по ip проиден
если 0 рядов - нет
если >1 - ошибка
 

Kuzmich_spb

Новичок
Предлагаю свой вариант кода который проверят IP

Первая часть записывает преобразованный списо в базу.

Струтура таблицы
PHP:
`id` int(11) NOT NULL auto_increment,
        `st_ip` int(11) NOT NULL default '0',
        `end_ip` int(11) NOT NULL default '0',
         PRIMARY KEY  (`id`)

Код который записывает список с в таблицу
PHP:
### Преобразуем диапазон сети 12.12.12.0/24 в 12.12.12.0 - 12.12.12.255
### Получим начальный и конечный IP

### Функция взята с [url]http://php.com.ua/forum/viewtopic.php?t=4405[/url]

function get_netrange($netrange){
    if (! eregi("/",$netrange)) $netrange = $netrange."/24";

    $limit = strpos($netrange, '/');

    $ip1 = ip2long(substr($netrange, 0, $limit));
    $mask = (int) substr($netrange, $limit+1);

    $key=0x80000000;
    $key >>= $mask-1;
    $key = ~ $key;

    $ip2 = $ip1 | $key;

    $ip[0] = $ip1;
    $ip[1] = $ip2;

    return $ip;
}

//***********************************************


### Открываем файл со списком сетей
### Записываем его в базу

$fd = fopen ("http://www.parkline.ru/rusnets/russia.txt",'r');

while (! feof($fd))
{
    $range = fgets($fd,256);
    if (strlen($range)>3)
    {
        $ips = get_netrange($range);
        $vals = "'".$ips[0]."','".$ips[1]."'";
        mysql_query("INSERT INTO $tbl_ips (st_ip, end_ip) VALUES ($vals)");
    }
}
fclose($fd);

/************************************************

код проверки
PHP:
$int_ip = ip2long($REMOTE_ADDR);
$result = mysql_query("SELECT id FROM $tbl_ips WHERE $int_ip BETWEEN st_ip AND end_ip");
if (mysql_numrows($result) > 0) print "ip ".$REMOTE_ADDR." is OK"; else print "ip ".$REMOTE_ADDR." is non russian";

Как работает можно посмотреть тут
http://qms9000.ru/ips/


У меня вопрос какую функцию лучше использовать для перобразования ip?.

INET_ATON в mysql и ip2long перобразуют по разному.

ip2long преобразует ip больше 127.255.255.255 в отрицательные числа, что позволяет хранить их в поле типа int.

INET_ATON ip больше 127.255.255.255 преобразует в положительные числа.
И значения этих функция разходятся.
 
Сверху