私はVoIPネットワークで多くの仕事をしています。 もちろん商用機器でも、しかしオープンソースではたくさんあります(記事はAsterisk PBXを使用するコンテキストで書かれています)。
テレフォニーには、多くの場合、ルートを特定の方向に分割するという単純なタスクがあります。 たとえば、たとえば、オペレータ1の方向、MG-オペレータ2の方向、MN-オペレータ3の方向の固定電話番号への直接呼び出し。
このタスクは一般に簡単で、アスタリスクに簡単に実装できます。
; : 7 ( 3- 7- ), .
exten => _0X,1,dial(SIP/itsp1/${EXTEN})
exten => _0XX,1,dial(SIP/itsp1/${EXTEN})
exten => _XXXXXXX,1,dial(SIP/itsp1/${EXTEN})
; : ( - "8") + 10 .
exten => _8[348]XXXXXXXXX,1,dial(SIP/itsp2/${EXTEN})
exten => _89XXXXXXXXX,1,dial(SIP/itsp2/${EXTEN})
; : ( - "810") + .
exten => _810X.,1,dial(SIP/itsp3/${EXTEN})
ただし、加入者に自分の地域の携帯電話のみへのアクセスを提供することが必要になる場合があり、ここでは単純な「_89XXXXXXXXX」で降りることができません。
問題の声明
実際には、モバイルオペレーターの電話コードは非地理的(いわゆるDEFコード)であるため、特定の地域にバインドされているコードはありません。 このため、たとえばコード「900」には、ヴォログダ州、プスコフ、チェチェン共和国などのオペレーターに属するバンドが含まれています。
モバイルオペレータは、理論的には、任意の地域で任意の空き範囲を割り当てることができます。これにより、異なる地域では、異なる番号の異なる範囲の電話番号が存在するという事実につながります。 たとえば、Vologda Oblastには46の異なる範囲があり、モスクワでは398です。
5100000-5109999(コード914では10000の数字)のように、すべての範囲が1000または10000の数字で「美しい」場合、すべてが多かれ少なかれ良好です。
しかし、多くの場合、10,000個の数値の大きな範囲は、その順序(範囲内の数値の順序)の倍数ではない数値のサブバンドに「カット」されます。 オフハンド:
コード | から | に | 収容人数 | 地域 |
958 | 2997500 | 2998749 | 1250 | アディゲ共和国 |
958 | 2998750 | 2999999 | 1250 | ウドムルト共和国 |
または、一般的に、1つの数字で(私はそれを与えません)。
同様の範囲(2997500-2998749)は、アスタリスクの1つの正規表現では記述できません。その結果、3つのルートが得られます。
exten => _89582997[5-9]XX,1,dial(SIP/itsp1/${EXTEN})
exten => _89582998[0-6]XX,1,dial(SIP/itsp1/${EXTEN})
exten => _895829987[0-4]X,1,dial(SIP/itsp1/${EXTEN})
そして、これは特定の範囲です。 領域全体を取得すると、正規表現の数が急激に増加します。 すべてに加えて、DEFコードは時間とともに変化する傾向があります。 いくつかは消え、他は現れます。 これを考慮しない場合、これはあなたの加入者がせいぜいあなたの地域の特定のバンドを呼び出すことができないという事実につながる可能性があります。
したがって、タスクは定式化されています。電話局が任意の数の範囲から認識する正規表現を作成する必要があります。
すべての情報源(MTT、ロシア連邦通信省)では、正確に表示されるのは範囲であり、正規表現ではありません。 ルートを作成する作業は退屈で日常的な作業であり、ロシア連邦のさまざまな地域で作業する必要があるため、自動化することにしました。 奇妙なことに、このための既製のツールは見つかりませんでした。
したがって、私は自分でツールを作成し、同時に全員と共有しました。 正規表現を作成するための一種のサービス:)。
解決策
任意の範囲(2633722-2673388)を取ります。 人はその基礎に基づいて簡単に正規表現を作成できます。 その結果、次のようになります。
サブレンジ | 正規表現 |
2633722-2633729 | _263372 [2-9] |
2633730-2633799 | _26337 [3-9] X |
2633800-2633999 | _2633 [8-9] XX |
2634000-2639999 | _263 [4-9] XXX |
2640000-2669999 | _26 [4-6] XXXX |
2670000-2672999 | _267 [0-2] XXX |
2673000-2673299 | _2673 [0-2] XX |
2673300-2673379 | _26733 [0-7] X |
2673380-2673388 | _267338 [0-8] |
これを自動的に行う方法を検討してください。
アルゴリズム
- 範囲と領域のリストを取得します。
FAS Webサイトから便利な表形式で範囲を取得します。 レジストリは、変更がなくても月に2回更新されます。 - リージョンの範囲のリストを取得します(リージョンはユーザーが入力します)。
作業の結果は、特定の地域の正規表現のリストになります。 - 最初の範囲をサブバンドに分割して、正規表現を作成できるようにします。
最も難しい部分。
最初に2つの要素(最小と最大)を含む二重リンクリストを作成し、各ステップで最後の要素の前に2つの数字が追加されます:最初の番号は最小値とともに新しい範囲になることができます(上の例を使用すると、最初のステップでは2633729です) 、2番目に-2633799など)、2番目の数値はもう1つです。 各ステップで、リストの最後から2番目の要素と最後の要素が考慮され、それらの間に2つの新しい要素が挿入されます。 2次元配列でうまくいくことはかなり可能でしたが、最初は、リストよりも記入するのが難しいと思っていました。
その結果、リストは数字のペアのセットになり、それぞれが「26337 [3-9] X」という形式の正規表現を作成できます。 - 各サブバンドから正規表現を作成します。
これは技術の問題です - 初期リストの各範囲で手順3と4を繰り返します。
実装と機能
私はPHPで書いた。 その結果、スクリプトは次のことができます。
- FAS Webサイトからレジスターをダウンロードし、UTF-8エンコードでCSVに持ってきます
- 選択した地域のアスタリスクダイヤリングプランを使用する準備ができている正規表現のリストをユーザーに表示します
- ボーナスが自然数の範囲を入力として受け入れ、正規表現のリストを返す方法
スクリーンショット:

執筆には多くの微妙な点があり、ここにリストする価値はほとんどありません。
ソースコードはこちらから入手できます 。 多くの改善点があります(これまでのところ、アルゴリズムの3番目の段落の前に範囲を合計し、他の形式の正規表現を追加するだけでなく、既存のAsteriskサーバー上のルートの定期的な更新を自動化するCLIからの作業を完了する予定です)、すべての願いを書いてください。 また、Webインターフェイスとセキュリティの観点からの推奨事項を聞いてうれしく思います。 私はプログラマーではないため、コードの品質が低下する可能性があります。
参照資料
- 動作中のスクリプト: http : //rootblog.ru/regex/
すべての地域名は、FAS Webサイトのレジストリから取得され、変更されていません。 - FASレジストリ: www.rossvyaz.ru/activity/num_resurs/registerNum
- 比較のために、MTT Webサイトの範囲: http : //www.mtt.ru/mtt/def
- ウィキペディア上のロシアの電話番号計画