Полный список украинских IP адресов

beg_mysql

Новичок
Полный список украинских IP адресов

Столкнулся с проблемой определения в скрипте принадлежности IP посетителя украинской зоне.

Нашел список украинских сетей http://colocall.net/ua/

Можно ли с точной уверенностью сказать, что если первые 2 разряда IP адреса совпадают с первыми двумя разрядами укр. сетей, то IP на 100% украинский?

Т.е. берем из списка укр. сетей (http://colocall.net/ua/) первый IP - 62.16.0.0
И утверждаем, что 62.16.*.* - украинский IP.

Если нет, то как?
 

Demiurg

Guest
адрес вида 62.16.0.0/19
означает, что в ip 62.16.0.0 первые 19 бит должны совпадать с искомым ip.
 

BabyKiller

Guest
Почитай про маски.

А насчёт примера Demiurg'а добавлю, что для лучшего понимания технологии масок, лучше всего ip адрес представлять в виде четырёх бинарных чисел:
00111110 00010000 00000000 00000000 - ip адрес 62.16.0.0
11111111 11111111 11100000 00000000 - маска которая может представляться как /19 или как 255.255.224.0
В кратце, маска работает как делитель ip адреса на две состоавляющие, на номер сети и номер узла. В вышеуказанном примере, адрес сети будет таким:
00111110 00010000 000 - номер сети
11111111 11111111 11100000 00000000 - маска
Это значит что ip адреса могут быть в этой стеи в диапазоне 62.16.0.0-62.16.31.255
 

beg_mysql

Новичок
Т.е. фактически первые 19 цифр (маска) – номер сети и он остается без изменения.
А какая логическая операция происходит с оставшимися 13 цифрами (номером узла) для определения диапазона?
Последние 13 цифр. все "1" - для диапазона.

Или для определения принадлежности IP - должны совпадать первые цифры - маска. Да?
 

ForJest

- свежая кровь
beg_mysql
Ты в состоянии определить какой год принадлежит какому веку?
1344
1586
1367
Как бы ты это делал? Сеть это век. Смысл понятен?
 

BabyKiller

Guest
Использую маску для ip адреса, получаем дипазаон адресов именно этой сетки:
00111110 00010000 00000000 00000000 - 62.16.0.0
00111110 00010000 00000000 00000001 - 62.16.0.1
. . .

00111110 00010000 00011111 11111110 - 62.16.31.254
00111110 00010000 00011111 11111111 - 62.16.31.255

Твой последний вопрос не понял, если ты хотел спросить принадлежит ли IP адрес конкретной сети, то проверяем только первые биты адреса, указанных в маске.
Т.е. если ip адрес имеет вид:
00111110 00010000 000XXXXX XXXXXXXX - то с уверенностью можно сказать что он принадлежит украинской сетке.
 

beg_mysql

Новичок
Автор оригинала: BabyKiller
Т.е. если ip адрес имеет вид:
00111110 00010000 000XXXXX XXXXXXXX - то с уверенностью можно сказать что он принадлежит украинской сетке.
Да именно это я и спрашивал, спасибо.

-~{}~ 07.01.05 17:47:

BabyKiller а на практике:::
$my_ip = ‘62.16.20.0’ // мой IP
$ukr_ip = ‘62.16.0.0/19’ // укр. сеть
$mask = split ("\/", $ukr_ip); // выделяем маску
$ukr_ip = split ("\.", $mask[0]); // разбиваем сеть поразрядно
$my_ip = split ("\.", $my_ip);
for ($i=0;$i<4;$i++) {
$ukr_ip[$i] = decbin($ukr_ip[$i]); // перегоняем в двоичный формат
$my_ip[$i] = decbin($my_ip[$i]);
}
$razr = floor((32-$mask[1])/8); // определяем кол-во разрядов, которые можно не сравнивать
$sdvig = (32-$mask[1])-$razr*8; // кол-во цифр, которое можно отрезать
Далее сравниваем $my_ip[0]==$ukr_ip[0]… [1]==[1]
А как сравнить первые (8-$sdvig) цифр 3-го разряда [2]???

Или можно сделать все проще?
 

Demiurg

Guest
beg_mysql
ты с бинарной логикой знаком ? тебе надо из числа 19 получить 11111111 11111111 11100000 00000000 потом две битовые операции и сравнение. split тут совсем не нужен.
 

beg_mysql

Новичок
Автор оригинала: Demiurg
beg_mysql
ты с бинарной логикой знаком ? тебе надо из числа 19 получить 11111111 11111111 11100000 00000000 потом две битовые операции и сравнение. split тут совсем не нужен.
Из 19-ти получить 11111111 11111111 11100000 00000000 проблем не вызывает, сравнение тоже.
Какие произвести битовые операции?
 

Demiurg

Guest
>Какие произвести битовые операции?
битовые and с обоими адресами.
 

BabyKiller

Guest
Кароче, вот вполне работоспособный код, можешь проверить на граничных значениях IP адреса 62.16.0.0-62.16.31.255

PHP:
$my_ip='62.16.20.0'; //Мой IP
$ukr_ip_mask='62.16.0.0/19'; //Украинский IP с префиксом
$ukr_ip_mask_split=explode("/",$ukr_ip_mask); //Украинский IP с маской разделён на IP и маску подсети
$my_ip_split=explode(".",$my_ip); //Мой IP разделён на четыре составляющие
$ukr_ip_split=explode(".",$ukr_ip_mask_split[0]); //Украинский IP разделён на четыре составляющие
$ukr_mask_bin=str_pad(str_pad('',$ukr_ip_mask_split[1],1,STR_PAD_LEFT),32,0,STR_PAD_RIGHT); //Двоичная запись маски подстеи
for($i=0;$i<4;$i++) //Прогоняем все четыре составляющие адреса
{
	$ukr_mask_split[$i]=bindec(substr($ukr_mask_bin,$i*8,8)); //Маска подсети
	$ukr_net_split[$i]=$ukr_mask_split[$i]&$ukr_ip_split[$i]; //Украинская подсеть
	$my_net_split[$i]=$ukr_mask_split[$i]&$my_ip_split[$i]; //Моя подсеть
}
$ukr_net=implode('.',$ukr_net_split); //Записываем Украинскую подсеть в одну строку
$my_net=implode('.',$my_net_split); //Записываем Мою подсеть в одну строку
if($ukr_net==$my_net)echo 'Это Украински IP';else echo 'IP не Украинский';
Если вопросы появятся пиши, если нет, то напиши хоть работает она у тебя или нет.

Вопрос к гуру: "Можно ли этот код как-то оптимизировать? Хотелось бы услышать ваши предложения, т.к. в php я новичок, то хотелось бы услышать комментарии"
 

beg_mysql

Новичок
BabyKiller
Да, скрипт, абсолютно рабочий, спасибо.

Касательно оптимизации видел скрипт на Perl
my $ip=shift;
print "IP-address $ip is ";
print "not " unless (&ukr_ip($ip));
print "ukrainian\n";
exit;

sub ukr_ip {
my $uaddr=shift;
map {
my ($oaddr,$mask)=split/\//,$_;
my $poaddr=unpack("L",pack("C4",(split (/\./, $oaddr))));
my $puaddr=unpack("L",pack("C4",(split (/\./, $uaddr))));
my $pmask=unpack("L",pack("B32",(1 x $mask)));
return 1 if (($puaddr & $pmask)==($poaddr & $pmask));
}(<DATA>);
return 0;
}


__DATA__
62.16.0.0/19
62.64.64.0/18
.....................

P.S> При переадресации header("Location: url") начала вылазить ошибка "Программа EXPLORER вызвала сбой .... в URLMON.DLL" связанная как пишут "из-за длинного URL"
Причем в 5-м IE и Opera (под WIN98) этого не было. А в 6-й IE - вылазит. В XP - проблем нет.
Ошибка не лечится SP1 и патчем Q813489
Можно ли пофиксить силами PHP?
 
Сверху