Generator of masks from intervals of DEF codes for Asterisk
What we have at the entrance:
At the output, we want to get a list of masks for determining the numbers of Moscow mobile operators (MCC, Beeline, MTS, MegaFon). To do this, a small script was written in a couple of hours, which probably can be useful to someone else and, with small changes, can be redone for other operators or other regions.
Upd .: DEF-code mask generator for Asterisk - now online =).
Currently I got the following result: from the table as of September 1, 2012 .
PS: the code is cruelly tied to the issuance of Rossvyaz, so the beginning of the interval always ends with zeros, and the end with nines. These are DEF codes - so there are seven digits.
PPS: just in case, I’ll clarify - yes, this is not the most beautiful code, but when you need an auxiliary script, then it’s possible =)
- several SIP operators for outgoing calls, and some have more “tasty" tariffs for a particular mobile operator;
- data on DEF codes on rossvyaz.ru for selected operators, but broken into intervals, including adjacent ones (especially noticeable for MegaFon);
- configured by Asterisk as an Elastix distribution .
At the output, we want to get a list of masks for determining the numbers of Moscow mobile operators (MCC, Beeline, MTS, MegaFon). To do this, a small script was written in a couple of hours, which probably can be useful to someone else and, with small changes, can be redone for other operators or other regions.
Upd .: DEF-code mask generator for Asterisk - now online =).
\s*\s*(\d+)\s*\s*\s*(\d+)\s*\s*\s*(\d+)\s*\s*\s*(\d+)\s*\s*\s*(.+?)\s*\s*\s*(.+?)\s*\s*|', $line, $matches)) {
if(!isset($defs[$matches[6]])) {
$defs[$matches[6]] = array();
}
if(!isset($defs[$matches[6]][$matches[5]])) {
$defs[$matches[6]][$matches[5]] = array();
}
$defs[$matches[6]][$matches[5]][] = array($matches[1],$matches[2],$matches[3]);
}
}
fclose($file);
// выбираем интересующие нас записи и объединяем смежные интервалы
$selected = array();
foreach($defs as $reg => $ops) {
if($reg == 'Москва и Московская область') {
foreach($ops as $op => $cs) {
usort($cs, "cmp_defs");
switch($op) {
case 'Московская сотовая связь':
case 'Вымпел-Коммуникации':
case 'Мобильные ТелеСистемы':
case 'МегаФон':
if(!isset($selected[$op])) {
$selected[$op] = array();
}
$newset = true; $cnt = 1;
foreach($cs as $cid => $c) {
if($newset) {
$selected[$op][] = array($c[0], $c[1]);
}
if(isset($cs[$cid+1]) && ($c[0] == $cs[$cid+1][0]) && (($c[2] + 1) == $cs[$cid+1][1])) {
$newset = false;
$cnt++;
} else {
$selected[$op][count($selected[$op]) - 1][2] = $c[2];
$newset = true;
$cnt = 1;
}
}
break;
}
}
}
}
// генерируем маски для Asterisk
$regs = array();
foreach($selected as $op => $defs) {
$regs[$op] = array();
foreach($defs as $def) {
// если кто будет разбираться, то здесь мозг отказал мне
// $leq - это про правую часть, а $req про левую =)
$pref = $def[0];
$first = $def[1];
$last = $def[2];
if($first > $last) {
$tmp = $first;
$first = $last;
$last = $tmp;
}
// маски разбиваем на три массива и вгоняем через unshift/push исключительно с целью удобства поиска ошибок =)
$r = array();
$rf = array();
$rl = array();
$req = 0;
for($i = 0; $i < 7; $i++) {
if($first[$i] === $last[$i]) {
$req++;
} else {
break;
}
}
$leq = 0;
for($i = 6; $i >= 0; $i--) {
if(($first[$i]) === "0" && ($last[$i] === "9")) {
$leq++;
} else {
break;
}
}
$zf = true;
$nl = true;
if($leq + $req < 6)
for($i = $leq; $i + $req < 6; $i++) {
$sl = 6 - $i;
$pf = substr($first, 0, 6 - $i);
$pl = substr($last, 0, 6 - $i);
if($pf < $pl) {
$x = $first[6 - $i];
if(!$zf || ($x != '0')) {
switch($x) {
case '9':
array_push($rf, $pref . $pf . '9' . str_repeat('X', $i));
break;
case '8':
array_push($rf, $pref . $pf . '[89]' . str_repeat('X', $i));
break;
default:
array_push($rf, $pref . $pf . '[' . $x . '-9]' . str_repeat('X', $i));
}
$first = sprintf('%0' . $sl . 'd', substr($first, 0, $sl) + 1 ) . str_repeat('0', 7 - $sl);
$zf = false;
}
$x = $last[6 - $i];
if(!$nl || ($x != 9)) {
switch($x) {
case '0':
array_unshift($rl, $pref . $pl . '0' . str_repeat('X', $i));
break;
case '1':
array_unshift($rl, $pref . $pl . '[01]' . str_repeat('X', $i));
break;
default:
array_unshift($rl, $pref . $pl . '[0-' . $x . ']' . str_repeat('X', $i));
}
$last = sprintf('%0' . $sl . 'd', substr($last, 0, $sl) - 1 ) . str_repeat('9', 7 - $sl);
$nl = false;
}
}
$leq++;
}
if($leq + $req <= 7) {
if($leq < 7) {
$sl = 6 - $leq;
$pf = substr($first, 0, 6 - $leq);
$pl = substr($last, 0, 6 - $leq);
$xf = $first[6 - $leq];
$xl = $last[6 - $leq];
if(($pf == $pl) && ($xf <= $xl)) {
if($xf == $xl) {
$r[] = $pref . $pf . $xf . str_repeat('X', $leq);
} elseif($xf + 1 == $xl) {
$r[] = $pref . $pf . '[' . $xf . $xl . ']' . str_repeat('X', $leq);
} else {
$r[] = $pref . $pf . '[' . $xf . '-' . $xl . ']' . str_repeat('X', $leq);
}
}
} else {
$r[] = $pref . str_repeat('X', $leq);
}
}
$regs[$op] = array_merge($regs[$op], $rf, $r, $rl);
}
}
foreach($regs as $op => $reg) {
echo "\n\n=== $op ===\n\n";
foreach($reg as $r) {
echo $linecode . $r . "\n";
}
}
function cmp_defs($a, $b) {
if($a[0] != $b[0])
return $a[0] - $b[0];
return $a[1] - $b[1];
}
?>
Currently I got the following result: from the table as of September 1, 2012 .
PS: the code is cruelly tied to the issuance of Rossvyaz, so the beginning of the interval always ends with zeros, and the end with nines. These are DEF codes - so there are seven digits.
PPS: just in case, I’ll clarify - yes, this is not the most beautiful code, but when you need an auxiliary script, then it’s possible =)