-
- /*-------------------------------------- --- ------------------------
- ip2アドレス [qqwry.dat]
- ------------------------- ------ --------------------*/
- class ip {
- var $fh //IP データベース ファイル ハンドル
- var $first;最初のインデックス
- var $last; // 最後のインデックス
- var $total; // 総インデックス数
- // コンストラクター関数
- function __construct() {
- $this->fh = fopen('qqwry.dat', 'rb) '); / /qqwry.dat ファイル
- $this->first = $this->getLong4();
- $this->last = $this->getLong4();
- $this->total = ($this ->last - $this->first) / 7; //各インデックスは 7 バイトです
- }
- //IP 関数の正当性をチェックします checkIp($ip) {
- $arr =explode ('.', $ip);
- if(count($arr) !=4 ) {
- return false;
- } else {
- for ($i=0; $i if ($arr[$ i] <'0' || $arr[$i] > '255') {
- return false;
- }
- }
- }
- return true;
- }
- function getLong4() {
- //少し読み取ります - 4 バイトのエンディアン エンコーディングを長整数に変換します
- $result = unpack('Vlong', fread($this->fh, 4));
- return $result['long'];
- }
- function getLong3() {
- //リトルエンディアンエンコーディングの 3 バイトを読み取り、long 整数に変換します
- $result = unpack('Vlong', fread($this->fh, 3).chr(0 ));
- return $result['long'];
- }
- //情報を問い合わせる
- function getInfo($data = "") {
- $char = fread($this->fh, 1);
- while ( ord($char ) != 0) { //国と地域の情報は0で終わります
- $data .= $char;
- $char = fread($this->fh, 1);
- }
- return $data;
- } bbs. it-home.org
- //エリア情報を問い合わせる
- function getArea() {
- $byte = fread($this->fh, 1); //フラグbyte
- switch (ord($byte)) {
- case 0 : $area = ''; //エリア情報なし
- case 1: //エリアがリダイレクトされる
- fseek($this->fh, $this->getLong3());
- $area = $this- >getInfo(); Break;
- ケース 2: //エリアがリダイレクトされる
- fseek($this->fh, $this->getLong3());
- $area = $this- >getInfo(); Break;
- デフォルト: $area = $this->getInfo($byte); // エリアはリダイレクトされません
- }
- return $area;
- }
- function ip2addr($ip) {
- if(!$ this -> checkIp($ip)){
- return false;
- }
- $ip = Pack('N', intval(ip2long($ip)));
- //二分探索
- $ l = 0;
- $ r = $this->total;
- while($l $m = Floor(($l + $r) / 2) //中間インデックスを計算します
- fseek($this- >fh, $this->first + $m * 7);
- $beginip = strrev(fread($this->fh, 4)) //中間インデックスの開始 IP アドレス
- fseek($ this->fh, $this->getLong3());
- $endip = strrev(fread($this->fh, 4)) //中間インデックスの終了 IP アドレス
- if ($ ip $r = $m - 1;
- } else {
- if ($ip > $endip) { //ユーザーのIP がより大きい場合 中間インデックスの終了 IP アドレスが
- の場合 $l = $m + 1;
- } else { //ユーザー IP が中間インデックスの IP 範囲内の場合
- $findip = $this-> ;first + $m * 7;
- Break ;
- }
- }
- }
- //国と地域の情報をクエリ
- fseek($this->fh, $findip);
- $location['beginip'] = long2ip( $this->getLong4()); / /ユーザー IP 範囲の開始アドレス
- $offset = $this->getlong3();
- fseek($this->fh, $offset);
- $location[ 'endip'] = long2ip($this->getLong4()) //ユーザーIP範囲の終了アドレス
- $byte = fread($this->fh, 1) //フラグバイト
- スイッチ(ord) ($byte)) {
- case 1: //国と地域の両方の情報がリダイレクトされます
- $countryOffset = $this->getLong3() //アドレスをリダイレクトします
- fseek($this->fh, $countryOffset);
- $byte = fread($this ->fh, 1); //フラグバイト
- switch (ord($byte)) {
- case 2: //国情報は 2 回リダイレクトされます
- fseek($this->fh , $this->gt ;getLong3());
- $location['country'] = $this->getInfo();
- fseek($this->fh, $countryOffset + 4);
- $location[' area'] = $this->getArea();
- Break;
- デフォルト: //国情報は 2 回リダイレクトされません
- $location['country'] = $this->getInfo($byte);
- $location ['area '] = $this->getArea();
- break;
- }
- break;
- ケース2: //国情報はリダイレクトされます
- fseek($this->fh, $this->getLong3( )) ;
- $location['country'] = $this->getInfo();
- fseek($this->fh, $offset + 8);
- $location['area'] = $this-> ;getArea ();
- Break;
- デフォルト: //国情報はリダイレクトされません
- $location['country'] = $this->getInfo($byte);
- $location['area'] = $this- > ;getArea();
- ブレーク;
- }
- //gb2312 to utf-8 (情報がない場合に表示されるCZ88.NETを削除)
- foreach ($location as $k => $v) {
- $location[$k] = str_replace('CZ88.NET' , '',iconv('gb2312', 'utf-8', $v));
- }
- return $location;
- }
- //デストラクター
- function __destruct() {
- fclose($this->fh ) ;
- }
- }
- $ip = new ip();
- $addr = $ip -> ip2addr('IP アドレス');
- print_r($addr);
- ?>
コードをコピー
|