PHPで高速に携帯ゲートウェイのIPから携帯キャリアを判別する
[追記]id:hetimaに指摘された、32bitアーキテクチャでの問題を修正。大感謝。
携帯電話からのWebアクセスゲートウェイのIPアドレスから、
携帯キャリアを判別したい場合がある。
通常は、id:tokuhiromによる
Net::CIDR::MobileJP(WWW::MobileCarrierJP)を使うといいと思う。
YAMLが出力されるので、さまざまな環境で利用ができるよ!
今回、PHPで携帯キャリアを判別したいと思ったんだけど、
PHPでYAMLを読んでその中身をすべて検査するなんてやだいやだい!
と沸き立つような強い衝動が。
というわけで、cidr-mobilejpというPythonスクリプトを書いた。
各携帯キャリアのページからCIDR情報をスクレイピングして、
その情報を元に携帯キャリアを(たぶん高速に)判別するPHPスクリプトを出力します。
DoCoMoについてはメールゲートウェイなどの余計なIPアドレスが入っちゃってますが、
実害ないでしょう。
id:tomisimaが書いていたスクリプトを基に、
AirHPhone対応を施したりいろんな改造をしました。
パフォーマンスは計って遅かったら泣くから計らない。
ip2longが遅い可能性が大いにあるんだよなー…
特徴1: CIDRでは別箇表示されるが、隣接したIPアドレス領域の扱い
CIDRではサブネットマスクでの範囲指定しかできないため、
ip2longやinet_atonが返す数値が隣接していても
ばらばらに記載しなければいけない場合があります。
cidr-mobilejpでは隣接したIPアドレス領域をまとめることによって
判別処理の高速化を図っています。
出力されたスクリプト
こんなスクリプトが出力されます。
以下のURLに出力されたスクリプトを置いておきます。
<?php /* This script is generated by scrape.py at 2010-07-27 17:53:08. http://svn.coderepos.org/share/lang/python/cidr-mobilejp/trunk/scrape.py */ function ip2mobile($ip) { $n = sprintf('%u', ip2long($ip)); if ($n < 1914044160) { if ($n < 1868151808) { if ($n < 1036427264) { if ($n < 1036419072) { if ($n < 1031078144) { if ($n >= 998712960 && $n <= 998713087) { return 'ezweb'; } } else if ($n <= 1031078159) { return 'ezweb'; } else { if ($n >= 1031078432 && $n <= 1031078447) { return 'ezweb'; } } } else if ($n <= 1036421631) { return 'airhphone'; } else { if ($n < 1036421888) { if ($n >= 1036421732 && $n <= 1036421735) { return 'airhphone'; } } else if ($n <= 1036421895) { return 'airhphone'; } else { if ($n < 1036422016) { } else if ($n <= 1036422063) { return 'airhphone'; } else { if ($n >= 1036422144 && $n <= 1036423167) { return 'airhphone'; } } } } } else if ($n <= 1036429055) { return 'airhphone'; } else { if ($n < 1036803072) { if ($n < 1036449792) { if ($n >= 1036429312 && $n <= 1036431359) { return 'airhphone'; } } else if ($n <= 1036451839) { return 'airhphone'; } else { if ($n < 1036779520) { } else if ($n <= 1036779775) { return 'airhphone'; } else { if ($n >= 1036780032 && $n <= 1036781439) { return 'airhphone'; } } } } else if ($n <= 1036804095) { return 'airhphone'; } else { if ($n < 1867943552) { if ($n >= 1867943232 && $n <= 1867943487) { return 'ezweb'; } } else if ($n <= 1867943743) { return 'ezweb'; } else { if ($n < 1867943872) { } else if ($n <= 1867943935) { return 'ezweb'; } else { if ($n >= 1867944704 && $n <= 1867944735) { return 'ezweb'; } } } } } } else if ($n <= 1868152831) { return 'docomo'; } else { if ($n < 1913928192) { if ($n < 1913926656) { if ($n < 1913925888) { if ($n >= 1913925888 && $n <= 1913926143) { return 'airhphone'; } } else if ($n <= 1913926399) { return 'airhphone'; } else { if ($n < 1913926144) { } else if ($n <= 1913926655) { return 'airhphone'; } else { if ($n >= 1913926400 && $n <= 1913926911) { return 'airhphone'; } } } } else if ($n <= 1913927423) { return 'airhphone'; } else { if ($n < 1913927424) { if ($n >= 1913927168 && $n <= 1913927679) { return 'airhphone'; } } else if ($n <= 1913927935) { return 'airhphone'; } else { if ($n < 1913927680) { } else if ($n <= 1913928191) { return 'airhphone'; } else { if ($n >= 1913927936 && $n <= 1913928447) { return 'airhphone'; } } } } } else if ($n <= 1913928703) { return 'airhphone'; } else { if ($n < 1913929472) { if ($n < 1913928704) { if ($n >= 1913928448 && $n <= 1913928959) { return 'airhphone'; } } else if ($n <= 1913929215) { return 'airhphone'; } else { if ($n < 1913928960) { } else if ($n <= 1913929471) { return 'airhphone'; } else { if ($n >= 1913929216 && $n <= 1913929727) { return 'airhphone'; } } } } else if ($n <= 1913929983) { return 'airhphone'; } else { if ($n < 1913929984) { if ($n >= 1913929728 && $n <= 1913930239) { return 'airhphone'; } } else if ($n <= 1913930495) { return 'airhphone'; } else { if ($n < 1913930240) { } else if ($n <= 1913930751) { return 'airhphone'; } else { if ($n >= 1913930496 && $n <= 1913930751) { return 'airhphone'; } } } } } } } else if ($n <= 1914044191) { return 'airhphone'; } else { if ($n < 3414870784) { if ($n < 2037376768) { if ($n < 1990165664) { if ($n < 1989727936) { if ($n >= 1914044160 && $n <= 1914044191) { return 'airhphone'; } } else if ($n <= 1989727999) { return 'ezweb'; } else { if ($n >= 1990165248 && $n <= 1990165375) { return 'ezweb'; } } } else if ($n <= 1990165695) { return 'ezweb'; } else { if ($n < 1990165952) { if ($n >= 1990165760 && $n <= 1990165887) { return 'ezweb'; } } else if ($n <= 1990166015) { return 'ezweb'; } else { if ($n < 2037375744) { } else if ($n <= 2037375871) { return 'ezweb'; } else { if ($n >= 2037375904 && $n <= 2037375935) { return 'ezweb'; } } } } } else if ($n <= 2037376895) { return 'ezweb'; } else { if ($n < 2098989824) { if ($n < 2070736352) { if ($n >= 2070736128 && $n <= 2070736159) { return 'softbank'; } } else if ($n <= 2070736383) { return 'softbank'; } else { if ($n < 2089987584) { } else if ($n <= 2089988095) { return 'docomo'; } else { if ($n >= 2098987008 && $n <= 2098989311) { return 'airhphone'; } } } } else if ($n <= 2098991615) { return 'airhphone'; } else { if ($n < 3405602816) { if ($n >= 3404050432 && $n <= 3404051455) { return 'docomo'; } } else if ($n <= 3405602847) { return 'softbank'; } else { if ($n < 3405603040) { } else if ($n <= 3405603071) { return 'softbank'; } else { if ($n >= 3414864896 && $n <= 3414865407) { return 'docomo'; } } } } } } else if ($n <= 3414871039) { return 'docomo'; } else { if ($n < 3548299392) { if ($n < 3534288384) { if ($n < 3532785600) { if ($n >= 3532169472 && $n <= 3532169727) { return 'docomo'; } } else if ($n <= 3532785663) { return 'softbank'; } else { if ($n < 3533263872) { } else if ($n <= 3533264127) { return 'docomo'; } else { if ($n >= 3533264384 && $n <= 3533264895) { return 'docomo'; } } } } else if ($n <= 3534288895) { return 'airhphone'; } else { if ($n < 3534684544) { if ($n >= 3534314496 && $n <= 3534316543) { return 'airhphone'; } } else if ($n <= 3534684671) { return 'softbank'; } else { if ($n < 3538321632) { } else if ($n <= 3538321647) { return 'ezweb'; } else { if ($n >= 3541231616 && $n <= 3541233663) { return 'airhphone'; } } } } } else if ($n <= 3548299519) { return 'airhphone'; } else { if ($n < 3682439424) { if ($n < 3681328384) { if ($n >= 3681288704 && $n <= 3681292287) { return 'airhphone'; } } else if ($n <= 3681328511) { return 'ezweb'; } else { if ($n < 3681328640) { } else if ($n <= 3681328671) { return 'ezweb'; } else { if ($n >= 3681328680 && $n <= 3681328687) { return 'ezweb'; } } } } else if ($n <= 3682439551) { return 'ezweb'; } else { if ($n < 3682440192) { if ($n >= 3682439680 && $n <= 3682439695) { return 'ezweb'; } } else if ($n <= 3682440319) { return 'ezweb'; } else { if ($n < 3715563520) { } else if ($n <= 3715566079) { return 'airhphone'; } else { if ($n >= 3724885632 && $n <= 3724886015) { return 'ezweb'; } } } } } } } return 'pc'; } ?>