Comments 33
бесплатно и даже без регистрацииможно и на сайте ЦНИИ пробить номер.
По одному — конечно, никаких проблем. Я дал ссылку в тексте, вот на всякий: zniis.ru/bdpn/check
Уж не сочтите за рекламу, но тут можно по-многу: xinit.ru/group_def
Единственное, база обновляется раз в одну-две недели, зато без капчи и списками.
Единственное, база обновляется раз в одну-две недели, зато без капчи и списками.
Работал в энергосбытовой компании, без проблем за несколько дней получил доступ к бдпн, но формат выкладки в виде csv конечно не очень современно. Да ещё было время у них с кодировкой там косяки были
Да, заполнил заявление, подписал директором, поставил печать и отправил по электронике. Потом созвонился для верности
На википедии есть статья со всеми странами операторами где первые 3-5 цифр это код оператора.
https://www.wikiwand.com/en/List_of_mobile_telephone_prefixes_by_country
Спасибо, отличный сервис.
Обратил внимание, что это довольно долгая операция. Это нормально, или мне не повезло просто?
Обратил внимание, что это довольно долгая операция. Это нормально, или мне не повезло просто?
Достаточно несложно автоматизируется запрос данных на сайте Россвязи и парсинг результатов запроса. Правда для большого количества номеров не использовал. Да и формат запроса может поменяться в любой момент (один раз уже пришлось переделать).
А капча? Распознавать картинку или проверка плохо проверяет?
На сайте Россвязи нет капчи.
rossvyaz.ru/deyatelnost/resurs-numeracii/vypiska-iz-reestra-sistemy-i-plana-numeracii
rossvyaz.ru/deyatelnost/resurs-numeracii/vypiska-iz-reestra-sistemy-i-plana-numeracii
Может быть кому пригодится, оставлю это здесь.
В одном проекте использую как раз эти базы — проблемы начинаются, когда нужно определять оператора для сотен тысяч номеров или миллионов за раз и быстро. Для этого подготовим базу:
В code_count записываем разницу между code_end — code_start + 1, сами номера храним в международном формате — 11 чисел, начиная с 7 (для России в частности) без всяких плюсов и пр., как того требует smpp-протокол и как принято у операторов. Получаем что-то подобное:
Интересным является поле Код оператора — это логическое разбиение операторов по признаку — тут уже каждый сам для себя определяет — в открытом доступе я этого не нашел (если у кого есть инфа — буду благодарен, мы же вычисляем по своей базе, опыту, запрашиваем информацию у других источников через api/вручную). Именно оно в проекте и важно (для определения цены :)
Php-класс для определения оператора для списка номеров:
Подгружаем номерные емкости в оперативу — сортируем по номерной емкости по убыванию, перебираем все емкости с учетом границ — просто сравнивая номера как числа.
При обновлении базы — номер сменил оператора — ищем старый диапазон и разбиваем его на два — до номера и после номера. Затем создаем новый — левая и правая границы равны номеру, емкость — 1. Релоадим кеш.
P. S.: Тот самый нужный код оператора при обновлении базы — ищем по названию нового оператора в базе — если есть таковой, то присваиваем его, в противном случае — помечаем как 'none' — и отправляем уведомление админу и менеджеру, что требуется вмешательство.
В одном проекте использую как раз эти базы — проблемы начинаются, когда нужно определять оператора для сотен тысяч номеров или миллионов за раз и быстро. Для этого подготовим базу:
SQL
CREATE TABLE `lb_phone_code` (
`id` int(11) NOT NULL,
`operator` varchar(30) NOT NULL COMMENT 'Код оператора',
`operator_name` varchar(200) NOT NULL COMMENT 'Имя оператора',
`region` int(11) NOT NULL COMMENT 'Регион',
`code_start` bigint(20) NOT NULL COMMENT 'Начало номерной емкости',
`code_end` bigint(20) NOT NULL COMMENT 'Конец номерной емкости',
`code_count` bigint(20) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `lb_phone_code`
ADD PRIMARY KEY (`id`);
ALTER TABLE `lb_phone_code`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
В code_count записываем разницу между code_end — code_start + 1, сами номера храним в международном формате — 11 чисел, начиная с 7 (для России в частности) без всяких плюсов и пр., как того требует smpp-протокол и как принято у операторов. Получаем что-то подобное:
Screenshot
Интересным является поле Код оператора — это логическое разбиение операторов по признаку — тут уже каждый сам для себя определяет — в открытом доступе я этого не нашел (если у кого есть инфа — буду благодарен, мы же вычисляем по своей базе, опыту, запрашиваем информацию у других источников через api/вручную). Именно оно в проекте и важно (для определения цены :)
Php-класс для определения оператора для списка номеров:
PHP
<?php
namespace app\admin\modules\phonecode\models;
use Yii;
use app\admin\modules\utils\Module as Utils;
/**
* This is the model class for table "lb_phone_code".
*
* @property int $id
* @property string $operator Код оператора
* @property string $operator_name Имя оператора
* @property int $region Регион
* @property int $code_start Начало номерной емкости
* @property int $code_end Конец номерной емкости
*/
class LbPhoneCode extends \yii\db\ActiveRecord
{
static private $list = null; // кеш емкости телефонов и операторов
/**
* @inheritdoc
*/
public static function tableName()
{
return 'lb_phone_code';
}
/**
* @inheritdoc
*/
public function rules()
{
return [
[['operator', 'operator_name', 'region', 'code_start', 'code_end'], 'required'],
[['region', 'code_start', 'code_end'], 'integer'],
[['operator'], 'string', 'max' => 30],
[['operator_name'], 'string', 'max' => 200],
];
}
/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'operator' => 'Код оператора',
'operator_name' => 'Имя оператора',
'region' => 'Регион',
'code_start' => 'Начало номерной емкости',
'code_end' => 'Конец номерной емкости',
];
}
/**
* @inheritdoc
* @return LbPhoneCodeQuery the active query used by this AR class.
*/
public static function find()
{
return new LbPhoneCodeQuery(get_called_class());
}
public static function getInfo($phone) {
/*if (empty($phone = Utils::getPhone($phone, -2))) {
return null;
}
$query = LbPhoneCode::find();
$query->andWhere(['<=', 'code_start', $phone]);
$query->andWhere(['>=', 'code_end', $phone]);
return $query->one();*/
// используем кеш, а также новый формат телефона с кодом страны
if (empty($phone = Utils::getPhone($phone))) {
return null;
}
$id = false;
/*$operator =*/ self::getOperator($phone, '', $id);
if ($id !== false) {
return self::findOne($id);
}
return null;
}
private static function initPhoneCodeList() {
if (self::$list === null) {
$query = "SELECT code_start s, code_end e, operator o, id i FROM lb_phone_code order by code_count DESC";
$l = Yii::$app->db->createCommand($query)->queryAll();
$min = $max = 0;
self::$list = [];
foreach ($l as $item) {
$item['s'] = (int) $item['s'];
$item['e'] = (int) $item['e'];
// вычисляем сразу лимиты, что бы не искать вне диаппазона
if ($min === 0 || $min > $item['s']) { $min = $item['s']; }
if ($max === 0 || $max < $item['e']) { $max = $item['e']; }
// начало диаппазона делаем ключом, чтобы не хранить лишнюю информацию,
// т. к. ключ все равно создается
self::$list['range'][$item['s']] = [
$item['e'],
$item['o'],
$item['i'], // добавим связь по id, чтобы найти полную инфу, какая строка сработала
];
}
self::$list['min'] = $min;
self::$list['max'] = $max;
}
return self::$list;
}
/**
* @param $phone - номер телефона, оператора которого ищем, не валидируется на корректность
* @param string $default_operator
* @param null $return_id - будет помещен id найденного оператора, либо false
* @return string
*/
public static function getOperator($phone, $default_operator = '', & $return_id = null) {
self::initPhoneCodeList();
$phone = (int) $phone;
if ($phone >= self::$list['min'] && $phone <= self::$list['max']) {
foreach (self::$list['range'] as $start => $item) {
if ($phone < $start || $phone > $item[0]) {
continue;
}
if ($return_id !== null) { $return_id = $item[2]; }
return $item[1];
}
}
if ($return_id !== null) { $return_id = false; }
return $default_operator;
}
/**
* @param $phone_list - список телефонов (будет изменен полученными результатами)
* @param string $default_operator - оператор по умолчанию, если не найден в базе
* @param bool $use_keys - телефоны указаны как ключи или как значение
* @param null $field_name - в какое поле помещать результат, если null, то заменят значение
*/
public static function getOperatorByList( & $phone_list, $default_operator = '', $use_keys = false, $field_name = null) {
if (empty($phone_list)) {
return;
}
if ( ! is_array($phone_list)) {
$phone_list = (array) $phone_list;
}
self::initPhoneCodeList();
// если нам передан просто массив телефонов, то делаем их ключами, чтобы
// напротив них разместить результат (оператора)
if ( ! $use_keys) {
$phone_list = array_flip($phone_list);
}
foreach ($phone_list as $key => $_) {
$phone = (int) $key;
$not_found = true;
if ($phone >= self::$list['min'] && $phone <= self::$list['max']) {
foreach (self::$list['range'] as $start => $item) {
if ($phone < $start || $phone > $item[0]) {
continue;
}
if ($field_name === null) {
$phone_list[$key] = $item[1];
} else {
$phone_list[$key][$field_name] = $item[1];
}
$not_found = false;
break;
}
}
if ($not_found) {
if ($field_name === null) {
$phone_list[$key] = $default_operator;
}
else {
$phone_list[$key][$field_name] = $default_operator;
}
}
}
}
}
Подгружаем номерные емкости в оперативу — сортируем по номерной емкости по убыванию, перебираем все емкости с учетом границ — просто сравнивая номера как числа.
При обновлении базы — номер сменил оператора — ищем старый диапазон и разбиваем его на два — до номера и после номера. Затем создаем новый — левая и правая границы равны номеру, емкость — 1. Релоадим кеш.
P. S.: Тот самый нужный код оператора при обновлении базы — ищем по названию нового оператора в базе — если есть таковой, то присваиваем его, в противном случае — помечаем как 'none' — и отправляем уведомление админу и менеджеру, что требуется вмешательство.
Определял регионы и коды еще в 2003 году.
В поиске набивал mtt def
До отмены мобильного рабства проблем вообще никаких не было
Тогда можно разбить клиентскую базу географически и не звонить ночами
Не будет работать если человек уехал из Сибири в Москву и не сменил номер.
спасибо за инфу
А разве «мобильное рабство» не ограничивает регион?
Я сталкивался неоднократно. Нельзя со своим номером уйди в другой федеральный округ.
Я сталкивался неоднократно. Нельзя со своим номером уйди в другой федеральный округ.
Ограничивает, в статье об этом есть.
Теперь закон разрешает: меняйте оператора, сохранив номер. Но, внимание, только внутри региона. Нельзя вытащить телефон из региона, предусмотренного Россвязью. Как нельзя и «сломать» диапазоны распределения номеров.
Нельзя вытащить телефон из региона, предусмотренного Россвязью. Как нельзя и «сломать» диапазоны распределения номеров.
А зачем тогда вообще доступ к базе перенесенных телефонных номеров?
Меняется оператор, ну и ладно. Регион же не меняется.
В своей подобной статье писал как именно это можно сделать, есть ссылка на исходный код.
Вчера получил звонок с номера +7-088-761-хххх, он был по делу, местный, подмосковный. Вроде как стационарный. Это что такой за оператор?
Sign up to leave a comment.
Как определить оператора и регион по номеру телефона