Sypex Geo — быстрое определение города по IP

    В начале года я публиковал статью Определение страны по IP: тестируем скорость алгоритмов, в которой упоминался мой «велосипед» отличающийся высокой скоростью работы. Одним из популярных вопросов стала возможность определения города по IP.

    И вот несколько месяцев спустя, проект начинавшийся, как «for fun» перерос в самостоятельный проект.
    Открыт отдельный сайт посвященный проекту Sypex Geo, на котором можно скачать свежие версии API и баз данных, а также ознакомиться с документацией.

    Для желающих скорее протестировать правильность определения города по IP — вот ссылка на демо-страницу. А под хабракатом, я опишу некоторые технические подробности и приведу результаты небольшого тестирования.

    Формат Sypex Geo 2.1


    С момента публикации последней статьи, формат Sypex Geo (сокращенно SxGeo) был оптимизирован, а также добавлена возможность включения в БД двух справочников — городов и регионов.

    При создании нового формата, ставились следующие приоритеты:
    • высокая скорость
    • низкое потребление ресурсов
    • открытость (спецификации формата бинарного файла БД и API открыты)
    • универсальность (возможность создания баз данных с любыми наборами данных)

    Формат позволяет хранить данные в разной кодировке. После выхода из беты, будут опубликованы скрипты для конвертирования базы данных из MySQL в бинарный файл БД.

    В БД хранится следующая информация:
    • ID страны
    • Код страны ISO 3166-1 (двухсимвольный)
    • Код региона FIPS 10-4 (двухсимвольный)
    • Название региона (опционально)
    • Город
    • Широта
    • Долгота
    • Timezone (опционально)

    Этот список может быть изменен и/или расширен при необходимости. Более подробную информацию о формате SxGeo 2.1 можно найти на сайте.

    Собственная база данных


    После весьма близкого знакомства с популярной системой геолокации GeoLite City от MaxMind, было принято решение о создании собственной базы данных. Проблема заключается в том, что в GeoLite City очень много неточностей, мусора, городов дубликатов, излишнего дробления диапазонов, а также проблем с городами бывшего СССР (например, вместо городов взяты названия фирм или имена ответственных из Whois).

    В данный момент база основана на GeoLite City, но уже содержит полностью переработанное покрытие России, Украины и Беларуси. Постепенно будут уточняться другие страны, в первую очередь СНГ и Европа. База данных Sypex Geo City содержит названия городов и регионов на русском языке в UTF-8 (встречаются еще не переведенные названия), а также timezone.

    Кроме того на сайте доступны другие базы данных преобразованные в формат SxGeo 2.1.

    Использование


    Использование Sypex Geo API максимально упрощено.
    1. Скопировать SxGeo.php и SxGeoCity.dat (или другие базы) на сервер
    2. Подключить файл SxGeo.php в свой скрипт, добавив строку
    
    include("SxGeo.php");
    
    3. Создать объект SxGeo
    
    //$SxGeo = new SxGeo(); // Режим по умолчанию, файл бд SxGeo.dat
    $SxGeo = new SxGeo('SxGeoCity.dat', SXGEO_BATCH | SXGEO_MEMORY); // Самый быстрый режим
    
    4. Определяем город (SxGeo City, GeoLite City, IpGeoBase)
    
    $SxGeo->get($ip); (возвращает информацию о городе, без названия региона и временной зоны)
    // $SxGeo->getCityFull($ip); (возвращает полную информацию о городе и регионе)
    

    Тестирование производительности


    И на десерт, небольшое сравнительное тестирование производительности. В качестве оппонентов выступают GeoLite API и Geobaza API. Все участники тестирования используют бинарную базу данных собственного формата, и используют API на PHP. Тестирование проходит под Win 7 (на Linux пропорции сохраняются), PHP 5.2.17.

    Результаты после 10 прогонов для каждого API в двух режимах (обычном и с кэшированием в памяти) усреднения и округления до десятков. Для каждого прогона создается массив из 50 000 случайных IP адресов, и в цикле осуществляется поиск каждым алгоритмом.


    Предложение и пожелание приветствуются. Также ищутся желающие помочь с портированием API на другие языки, и созданием модулей для Apache и nginx.
    Поделиться публикацией
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама
    Комментарии 84
    • 0
      Город по IP вычислен правильно (Николаев, Украина), но…

      Timezone: Europe/Zaporozhye

      Это как? Что-то я не слышал про Запорожский часовой пояс :)
        • +2
          Тем не менее, такой есть, к примеру вот в доках по PHP. Вполне возможно, что когда-то запорожское время не совпадало с киевским временем.
          У самого был соблазн поубирать к примеру для Украины все, кроме киевского времени, но потом решил оставить так, как пишут в различных справочниках.
          • 0
            Крымское время как-то не совпадало. А запорожское — никогда :)

            • +1
              Ну это уже больше вопрос к создателям этих самых timezone :)
          • 0
            Это вы просто Ubuntu не ставили в украинскую временную зону.
            Нужно хорошо пощелкать мышкой в районе Украины, что бы Запорожье сменилось на Киев.
          • 0
            Город по IP вычислен неправильно. Это, пожалуй, классика жанра, что Сургут (static ip, через Уралсвязьинформ) в 90% баз определяется как Ханты-Мансийск или как Курган, но ни в коем случае не Сургут :) Встречал базы, где это разделение четкое и особенности УСИ предусмотрены.
            • 0
              Если можно IP скиньте в личку поправим.
              • 0
                Скинул, но мой IP такой не один. Проблема намного глобальнее.
                • 0
                  Не знаю, реально ли поправить, но Украинский провайдер 3G интернета Intertelecom выдает динамические IP адреса, и все они определяются как в Одессе, хотя физически я нахожусь в Киевской области. Это можно поправить? Любые сервисы определяют так.
                  • 0
                    Никак это нельзя поправить. Сегодня этот IP в одном городе, а завтра в другом. Пишется место где он зарегистрирован.
                • +1
                  да там таких примеров полно — несколько провайдеров работают по всей Сибири. Я думаю что в европейской части тоже должны быть неверные блоки от федералов
                  • 0
                    Да, у меня проводной Билайн одно время частенько определялся как московский, хотя пользовался я им в Питере.
                • +2
                  Пока переходил с 2.0.0 на новую версию, обнаружил, что константа SXGEO_FILE не определена, а в документации написано «Второй параметр — режим работы: SXGEO_FILE (работа с файлом базы, режим по умолчанию)». И метода getCountry($ip) не существует, хотя в док. он есть: "$country = $SxGeo->getCountry($ip); (возвращает двухзначный ISO-код страны)". Кстати, я не нашел в классе ни одной функции, определяющей только страну (get_cc() в пред. версии). Документация тут: sypexgeo.net/ru/docs/
                  • 0
                    Спасибо за замечание, почему-то API не последней редакции залито было, сейчас обновил файл, там SXGEO_FILE вернулось, да и его можно пропускать.
                    Страну возвращают $SxGeo->getCountry($ip) или просто $SxGeo->get($ip)
                  • 0
                    Промахнулось, примерно на 2500 км. Туннелей нет, если что.
                    • 0
                      Если можно IP скиньте в личку поправим.
                      • 0
                        Сейчас пытаюсь выяснить, похоже что всё таки меня здесь развернули через прозрачный прокси, так что возможно и погорячился.
                    • +2
                      Зашёл из Томска:

                      image

                      Город определился почти верно, к нему претензий нет: в конце концов, такие записи почти во всех базах RIPE. Но почему на карте Украина? :-)
                      • 0
                        Там тоже Северск есть, тут скорее всего вопрос как ищется место на карте и как определяются координаты.
                        • +1
                          Да, похоже, Вы правы. Тут явно речь идёт о Северске донецкой области, даже координаты совпадают.

                          Что, однако, не отменяет моего подозрения об ошибке в базе, а наоборот, усиливает.
                          • 0
                            Проверим, бывают просто ошибки, код страны один, а в адресе город и страна другие.
                      • 0
                        Кстати, к городам из США неплохо было бы прилепить двухбуквенный код штата, в котором они находятся. Иначе город Cambridge, например, в штате Massachusetts ничем не будет отличаться от одноименного города в шт. Maryland или Vermont. Поля lon-lat могут помочь только на карте.
                        • 0
                          Так штат должен в регионе показываться. Код есть, так же как и FIPS коды областей.
                        • +2
                          Сейчас в проектах использую MaxMind, платно, но зато базы постоянно обновляются и вообще, находятся в достаточно актуальном состоянии.
                          Как правило, все открытые проекты грешат низкой скоростью обновления и постоянными огрехами. В свое время именно поэтому в свое время отказался от ipgeobase.
                          Как будет обстоять с этим вопросом в SypexGeo?
                          • 0
                            Все подобные проекты обречены на огрехи. Причина очень проста — БД строится по информации из RIR (RIPE, ARIN и т.д.). Т.е. по сети определяется владелец, по владельцу определяется местоположение. У самого же объекта network нету поля «город». Вот и получается, что если провайдер предоставляет услуги в нескольких городах/регионах, то все его сети числятся за «домашним городом».

                            Как-то так в первом приближении. Возможно автор меня поправит.
                            • 0
                              А бывает такое что в «домашнем городе» провайдер вообще не предоставляет услуги?
                              • 0
                                Я думаю чисто принципиально такое возможно, но вряд ли часто встречается.
                              • 0
                                Вопрос не в огрехах (понятно, что без этого обойтись не получится), а в скорости их исправления.
                                • 0
                                  Скорость исправления, в данном случае, зависит не только от доброй воли автора проект (исправления ручные), но и от доброй воли провайдеров (только они знают в каком городе какие их сети). Провайдерам, как вы сами понимаете, глубоко чихать на подобные сервисы.
                              • 0
                                В планах как раз обновляться с частотой MaxMind, для начала просто нужно подчистим базу. Ну и учитывая открытость самого формата в него можно будет конвертировать самостоятельно.

                                А сколько кстати размер бинарной базы у платного GeoIP, и как она обновляется полностью файл качается или только разница?
                                • 0
                                  Вообще, если аккумулировать в единое целое информацию из нескольких баз, может получится и интересный вариант.

                                  Насчет размера не знаю, я пользуюсь запросами к базе через API
                              • НЛО прилетело и опубликовало эту надпись здесь
                                • +4
                                  не всегда разрешено, а если разрешено, не всегда отдает. не всегда на том конце современный браузер, да и браузер то не всегда. Да и другого конца может и не быть — просто список адресов, и все
                                • 0
                                  Собственно так и не увидел сравнение с правильно настроенным запросом в базу mysql. В комментах к первой статье несколько раз писали что и сравнение надо делать по одному полю и индекс правильно настроить. Могу лишь добавить что если пошаманить с буферами, то скорость будет в миллионы запросов в секунду

                                  Есть суровое подозрение что самописный поиск при прочих равных не сможет реально дать большую скорость чем поиск по хешированному индексу, весь вопрос в том сколько ему дали памяти
                                  • 0
                                    Прежде чем подозревать, проведите тесты сами. Это не так сложно.
                                    Или, в крайнем случае, разберитесь в алгоритмах. Благо они не такие большие.
                                    • +1
                                      Во-во, хеш дает O(1) а поиск O(logn(n)) в лучшем случае :)
                                    • 0
                                      Я как раз собираюсь написать еще одну статью с подробным тестированием, в том числе разных вариантов MySQL запросов. Можете прислать свой вариант правильного запроса к MySQL, я его протестирую.
                                    • +1
                                      Может это уже слишком, и я не знаю есть ли это в других базах, но был бы полезным столбец с основными языками, используемыми в стране.
                                      • 0
                                        Это в принципе легко добавить. Сейчас собирается подробная инфа по городам (индексы, телефонные коды, численность населения) можно и языки добавить
                                      • 0
                                        Жаль IPv6 нет.
                                        • 0
                                          Ну не всё сразу, постепенно будем расширяться :)
                                        • 0
                                          85.15.175.10 Координаты: 56.8333, 60.6
                                          Город: Екатеринбург,
                                          Регион: Свердловская область,

                                          Из Тюмени зашел через университетский wi-fi (канал предоставлен Екб-м провайдером, правильно)

                                          зы: (через свой инет все правильно определяет)
                                          • 0
                                            Видимо wifi в ТюмГУ ;)
                                            У меня ip 85.15.175.253, тоже показывает, что г.Екатеринбург, но я так же зашел из г.Тюмень.
                                          • +3
                                            Как уже сказал MechanisM выше, хотелось бы IPv6, чтобы было инновационнее, чем у других. Правда туннельные брокеры «сломают» правильность определения местоположения.
                                            Если верить местным (омским) представителям провайдера Билайн, то пул IP-адресов для домашнего интернета един на всю страну, поэтому сидя в одном и том же городе, разрывая сессию можно добиться местоположения и Смоленск, и Волгоград.
                                            • +1
                                              Благодаря туннельным брокерам наконец то будет искоренена проблема ip дискриминации
                                            • 0
                                              Город определил правильно — Пенза, но часовой пояс почему-то Самары.
                                              • 0
                                                А рабочий IP — 79.133.89.XXX определил в Москве. На самом деле опять же Пенза.
                                              • +1
                                                Украинское ОГО! (Укртелеком) похоже определяет как Киев.

                                                Например, 95.135.190.8 — Здолбунов, ровенская область.
                                                • 0
                                                  И это не удивительно, определяет так же как и все другие подобные сервисы определения города.
                                                  Вряд ли это возможно исправить без договорённости с Укртелекомом
                                                  (чтобы знать в каком городе из какого диапазона выделяются ip).
                                                  • –2
                                                    Вы хотите чтобы провайдер просто так, по запросу неизвестной частной фирмы, раскрыл адрес своего клиента?
                                                  • 0
                                                    Ну с крупными провайдерами, точности добиться сложно, так как они зачастую тасуют IP как угодно.
                                                  • 0
                                                    2.92.139.74 ростов билайн провод
                                                    определяет как москва
                                                    • 0
                                                      С Билайном проблематично, еще ни разу у меня верно ip не был определен. Подозреваю, что у них общий пул на всю Россию, что было подтверждено комментарием выше.
                                                    • +2
                                                      Данные по России более свежие и актуальные у ipgeobase, причем делается на базе RIPN и обновляется ежедневно.
                                                      • 0
                                                        Огромное спасибо за проект (и вообще, пользуясь случаем, за все sypex*), очень пригодится.
                                                        Одна маленькая идея, родилась после прочтения комментариев к топику — вы бы добавили кнопочку «Город определен неверно, правильный город ...», тогда бы после публикации имели список диапазонов, по которым определение идет неверно.
                                                        • 0
                                                          Спасибо, обязательно добавим кнопочку.
                                                          Кстати под брендом Sypex готовится еще 2 проекта :)
                                                        • 0
                                                          Нахожусь в Смоленске, но сервис утверждает, что в Перми.
                                                          • –4
                                                            Никто еще в комментариях не запостил картинку «Как вычислить по IP… for dummies»? Я удивлен.
                                                            • 0
                                                              Для американского IP показывает русское название штата и города. Мне кажется это неправильный подход.
                                                              • 0
                                                                Если Вы используете базу Sypex Geo City которая должна быть на русском языке, то вполне логично, что названия иностранных городов в ней будут на русском.

                                                                Если Вам нужны названия мест на английском, то используте базу GeoLite City.
                                                                • 0
                                                                  Я использовал демо страничку. Наверное будет логично иметь версии на двух разных языках.
                                                                • 0
                                                                  Это пока в бете идет уточнение базы, нужно чтобы просто параллельно собиралась обратная связь, от потенциальных пользователей. Все данные сейчас собираются на русском и английском, в дальнейшем будут версии Sypex Geo City на двух языках.
                                                                  • 0
                                                                    Простите, я так и не нашел на сайте кнопочку «Город определен не верно»
                                                                • 0
                                                                  > Для системы статистики нашей Sypex CMS…
                                                                  Нагуглил вот это: sypex.net/ru/cms/, но там нет никакого описания. Не собираетесь ли рассказать об этой системе на хабре или у себя на сайте?
                                                                  • +1
                                                                    Нахожусь в Нью-Йорке, провайдер Time Warner Cable. Определило с точностью до континента)

                                                                    • 0
                                                                      Данные по штатам по сути, такие же как в Geo Lite City, сейчас работаем в первую очередь над СНГ и Европой.
                                                                    • 0
                                                                      Документацию бы чуточку подробнее.
                                                                      • 0
                                                                        Документации по использованию и о самом формате?
                                                                        • 0
                                                                          Например, чтобы узнать имена ключей выходного массива, пришлось его сперва целиком выводить)
                                                                      • 0
                                                                        Недавно зашел на яндекс-карты, так они не просто мой город определили, а даже дом на карте указали. Вот как так они делают?
                                                                        • 0
                                                                          IP сотовых операторов определяет часто неверно. Для Восточной Сибири у МТС (да и у других операторов наверняка тоже) часто показывает как Хабаровск.
                                                                          Еще есть отдельная проблема с Opera mini.
                                                                          • 0
                                                                            Попробовал 2 адреса. Один — Центральный телеграф в Красногорске, определился как Москва, в общем-то ладно, довольно близко. Второй — ТВТ в Набережных Челнах, определился как Казань. Да еще и time zone Europe/Samara. Судя по описанию, Europe/Samara только в Самарской области и Удмуртии, а Казань — Татарстан, там Europe/Moscow.
                                                                            • 0
                                                                              178.137.20.* пишет Украина \ Киев
                                                                              я в Украина \ Донецкая обл \ Макеевка
                                                                              • 0
                                                                                2.92.91.xx — пишет, что Брянск, хотя на самом деле я из Саратова.
                                                                                Но пользуюсь домашним интернетом от билайн, их IP очень редко правильно распознаются.
                                                                                • НЛО прилетело и опубликовало эту надпись здесь
                                                                                  • 0
                                                                                    Будут ли обновления базы по адресам?
                                                                                    • 0
                                                                                      Да, как раз вчера обновились.
                                                                                      • 0
                                                                                        Супер, спасибо. Проверил адреса, которые раньше не определялись, теперь все ОК.
                                                                                    • 0
                                                                                      Внедрен на проекте в 200к+ визитов в сутки. Полет отличный.
                                                                                      • 0
                                                                                        а что с модулем для nginx? есть какие-нибудь движения в эту сторону?
                                                                                        • 0
                                                                                          В демке json отдается без экранирования апострофов, что приводит к ошибки парсинга.
                                                                                          • 0
                                                                                            Увы… но мой город тоже не определился правильно… при том что в самой базе название моего города есть…

                                                                                            image
                                                                                            • 0
                                                                                              А какой IP (можно в личку)? Проверим.

                                                                                            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.