На днях понадобилось мне научится определять к какому мобильному оператору принадлежит тот или иной номер сотового телефона. К сожалению гугл не нашел ни одной готовой базы или какой либо разработки в этом направлении. (Вру, есть пару сайтов определяющих оператора, но работают они только с российскими операторами, а мне нужен весь мир)
Но зато я нашел вот такую вот интересную, на мой взгляд, базу Коды сотовых операторов мира.
Конечно формат немного не тот что нужен, да и для прямого скачивания ее нигде нет. Пришлось написать парсер и спарсить все данные с html страниц напрямую. Под катом архив с базой, примером и описанием того как определять оператора по номеру.
Теория
Как же определить оператора по телефонному номеру? Как вы знаете любой «станционарный» номер состоит из
+[КОД-СТРАНЫ][КОД-ГОРОДА][КОД-АБОНЕНТА]
Ну а в сотовых сетях это выглядит вот так:
+[КОД-СТРАНЫ][ПРЕФИКС][КОД-АБОНЕНТА]
Один оператор может иметь множество префиксов. Но каждый префикс уникален и его не может быть у двух операторов одновременно в одной и той же стране. Если вы проследили за этой логикой, то вы поймете что связка +[КОД-СТРАНЫ][ПРЕФИКС]
уникальна, и принадлежит только одному оператору. Т.е. осталось собрать базу по кодам стран и используемым префиксам и мы сможем определять мобильных операторов по телефонным номерам.
Конечно невозможно определить всех операторов для каждого номера, так как:
- Например в Канаде и США, нет специальных префиксов для мобильных операторов
- Во многих европейских странах можно сменить оператора БЕЗ смены номера, т.е префикс останется прежним
Есть еще одна проблема. Длина кодов различных стран различается, да и префиксы тоже бывают разной длины. Т.е выделить код страны и префикс довольно проблематично. Но на самом деле работа с номерами ведется в виде дерева, т.е если схематично представить получится как то так:
Серые прямоугольники — узлы, а зеленые — конец ветки. Плюс — это выход на международную связь и затем по дереву к необходимой стране. Кстати обратите внимание на следующий момент:
+7 - код России
+77 - код Казахстана
Вроде бы пересечение диапазонов? Но на самом деле ничего страшного тут нет. Дело в том что в России семерка никогда не будет следующей цифрой после кода страны. (Не верите? Поищите в справочнике телефнных номеров России код города начинающийся на 7)
Собственно если вы поймете принцип определения кода страны с помощью дерева, то вы поймете что и префикс каждого оператора строится по такому же принципу.
Практика
Конечно выше я описал идею идеального алгоритма, но на практике я не стал заморачиватся с поиском по дереву и представил все данные в виде таблицы. Оператор находится за 3-5 запросов. Для меня это является достаточным результатом.
Вот пример кода для поиска по моей БД:
function GetOpsosByNumber($number){
$number=preg_replace('#[^\d]#', '', $number);
for($i=7; $i>=3; $i--){
$tmp=substr($number, 0, $i);
$data=mysql_query('SELECT * FROM opsos WHERE `code_full`=\''.$tmp.'\'');
if(mysql_num_rows($data)){
return $data;
}
}
return null;
}
Как видите от номера отрезается сначала 7 символов и эта часть ищется в БД, затем 6 символов и так до 3 символов или до появления первого результата. Почему от 7 и до 3? Потому что на данный в БД максимальная длина связки «[КОД-СТРАНЫ][ПРЕФИКС]» — 7 цифр, а минимальная 3 цифры.
К сожалению существующая база для некоторых номеров опеределяет по несколько операторов, так как эта база не содержит всех префиксов, но найти полную базу всех префиксов невозможно впринципе, так что прийдется довольствоваться тем что есть.
Cтруктура БД. Таблица «opsos»:
- code_country — код страны
- code_dex — префикс
- code_full — код страны+префикс
- country — двубуквенный код страны оператора
- name — название оператора
- name_sub — «дополнительные» имена оператора
- name_image — имя картинки-логотипа оператора
Таблица «countries»:
- short — двубуквенный код страны
- full_rus — полное название страны на русском
- full_eng — полное название страны на английском
Исходники
Внимание! В этом посте выложенна старая версия базы, новую версию смотреть здесь.
В архиве картинки-логотипы для каждого из операторов и дамп необходимых таблиц
Скачать: sources.zip (740 Kb)
Спасибо!
Всегда рад помочь! =)
Если захочешь допилить, то вот точная база для всех Российских операторов http://www.rossvyaz.ru/docs/articles/DEF-9x.html .
Избавит проблему определения сразу нескольких операторов.
О, спасибо, пригодится. Я тут на днях немного структуру самой базы изменил, и как раз добавлю эту.
Про Казахстан у тебя немного не то.
Там код такой же как унас +7, дальше идет просто 7хх, а у нас 9хх. А в твоей базе получается 77701 полный код Актива, хотя полный там 7701) Пришлось самому править
Хм, вот ведь отстой =(
Всегда считал что у них код +77, а оказывается у нас с ними поделена зона. Плюс еще в седьмую зону вошли абхазия и южная осетия. Т.о. вообщем получается такая картина:
И хз как это все красиво оформить в базе. Ладно, займусь на днях.
Кстати, нашел вот такой вот ресурс:
http://www.numberingplans.com/?page=databases
Только ссылки не кликабельны, или я дурак(?)
Да полная беда с этими операторами))
А на сайте зарегиться надо чтобы скачать. Или вот:
https://www.numberingplans.com/download/E164_PSTN_samplecsv_v1203.zip
https://www.numberingplans.com/download/E212_IMSI_samplecsv_v1203.csv
https://www.numberingplans.com/download/Q708_ISPC_samplecsv_v1203.csv
https://www.numberingplans.com/download/TW06_IMEI_samplecsv_v1203.csv
Наверное прийдется пересмотреть структуру Бд в сторону представления в виде дерева. Хотя не уверен стоит ли. Может просто вставить небольшой костыль для россии/казахстана? По сути такая неоднозначность в кодах стран только в зоне +7. В остальных же случаях каждая страна — уникальный код страны. Вообщем как вы думаете?
PS: спасибо за ссылки (оказывается я дурак :D)
Я бы пересмотрел структуру базы с учетом того, что надо точно определять российских операторов по ссылке http://www.rossvyaz.ru/docs/articles/DEF-9x.html . Но мне пока это не горит, поэтому оставляю это на вас! Спасибо!)
А зачем такая избыточность {code_country, code_dex, code_full}? Если я правильно понимаю, то code_full легко получается конкатенацией полей code_country и code_dex.
Я бы хранил префиксы целиком и делал бы поиск в два этапа: поиск страны; поиск оператора в стране…
Проблема в том что из code_full, сложно потом получить код страны и префикс, это сделанно лишь для этого
Спасибо огромное за базу! Очень выручил!=)
Спасибо, выручили!
Спасибо большое!