Окт 23
2008GeoEngine Beta1.0
Рубрики: (Геотаргетинггггг) Автор: phpdude 23-10-2008
Теги : blast, php, ахуенно, бесплатно, Геотаргетинггггг, полезные штуки
Ладно, не буду терзать. В этом топике я раскрою всю тайну сего движка.
Плюсы данной реализации:
- Высокая скорость поиска
- Слишком мало кода, чтобы давать какую либо нагрузку к основному проекту
- Возможность автоматического обновления базы данных ip адресов
- Можно использовать бусплатно (Лицензия LGPL)
Минус только пожалуй один: достаточно большой файл базы данных (порядка 16 мегабайт).
Как это работает
Основная идея была – быстрый поиск кода страны для известного IP адреса. Поэтому использовался обычный файл в роли базы данных, никаких MySql серверов или подобных узких мест.
Аналитика
0.0.0.0 – 255.255.255.255 = 2^32 = 4 294 967 296 ip адресов.
Посчитав количество стран, я пришел к выводу, что их не более 255, соответственно можно использовать 1 байт для записи отношения ip адреса к стране.
Почитав про провайдеров интернета и услуги предоставления пулов ip адресов, я пришел к выводу, что ip адреса продают пачками не менее 256 штук, если быть более точным то даже не менее 4096 адресов (могу ошибаться). Тогда вывод: для того, чтобы записать карту стран => ip адресов, достаточно 16 777 216 байт, а это уже прелестно по сравнению с 4 294 967 296.
Собственно вот оно и решение задачи: использовать подсети, а не ip адреса.
Алгоритм: на входе имеем ip адрес, например 84.234.123.43, отрезаем его до последней точки, получаем 84.234.123. далее добавляем в конец 0, получаем 84.234.123.0. Клево!
)
Переводим этот ip адрес в long с помощью функции ip2long.
Получаем некоторое число, которое для нас будет offset’ом в файле базы данных, и прочитанный байт – является кодом страны. По-моему прикольный алгоритм, ну что, оценим скорость?
50000 ips for 1.28169393539 seconds.
1 ip for 0.000026
Я не встречал таких же скоростных реализаций на пхп, хотя может на сегодняшний день есть нечто подобное.
<?
include(”geo.php”);
<p>$geo = new Geo(”geo.dat”);
<p>$ips = array();
for($i=0;$i<50000;$i++)
{
$ips[] = long2ip(rand());
}
$start = microtime(true);
foreach($ips as $ip)
{
$geo->ip2country($ip);
}
$end = microtime(true);
echo “50000 ips for “.($end-$start).” seconds.<br/>1 ip for “.sprintf(”%f”,(($end-$start)/50000));
?>
Исходники вы можете скачать phpdude GeoEngine.
Архив содержит 4 файла: geo.dat, geo.php, update.php, index.php
geo.dat – файл базы данных
geo.php – класс Geo
update.php – умеет обновлять базу данных до последней версии ripn.net’а
index.php – бенчмарк тест.
Жду отзывов
Всея ПЫХА
adw0rd
Мавр
ГО
Irinax
Dude, прикольно! =) Голова работает. Но только блин вот эти двухбуквенные аббревиатуры как расшифровать? =)
это стандартные коды для стран, насколько я помню
по крайней мере я точно знаю что не стал бы делать так, как знаю только сам, всегд все делаю по стандартам и вам того же желаю)
Ой где нашел))) у самизнаетекого на сайте.
http://www.artlebedev.ru/tools/country-list/
вот тут расшифровка, думаю что с моими должны совпасть.
блестяще!!! вот бы еще города..))
мне не нужны были города
можете воплотить идею также, думаю 3 байта хватит на все города, ну максимум 4)))))
вопрос где взять базы. если найдете базу городов и допишите, думаю что все только признательны будут
Города: http://ipgeobase.ru/cgi-bin/AdvSearch.cgi
База: http://ipgeobase.ru/cgi-bin/Archive.cgi
Архив базы данных местоположений блоков IP-адресов, выделенных RIPE локальным интернет-реестрам (LIR-ам) для использования в Российской Федерации (см. Основные данные). Также здесь вы найдете свежий архив с географическими координатами городов российских блоков IP адресов (см. Дополнительные данные).
geoengine тоже оттуда берет данные, насчет городов .. мне это было не интересно, но сделать как я уже заметил подобную вещь + для городов при наличии баз – посрать сходить. идея ценна! по крайней мере для меня.
Просматриваю тут БД от http://www.maxmind.com... хм, не все диапазоны с 0 начинаются
4.20.73.16,»4.20.73.31″,»68438288″,»68438303″,»CA»,»Canada»
4.20.73.32,»4.23.128.183″,»68438304″,»68649143″,»US»,»United States»
4.23.128.184,»4.23.128.191″,»68649144″,»68649151″,»CA»,»Canada»
Да и простенький запрос в RIPE для одной подсетки не всегда возвращает одну и ту же страну
хреново чо сказать))))))
проиндексить бы ее да посмотреть, но пока не до етого
А вот здесь есть апишка де все отлично и быстро работает, платные базы с мегаточным геотаргетингом и заботиться про вас тут будут…
http://services.my-addr.com