ホームページ  >  記事  >  バックエンド開発  >  PHP が無害な IP データベースを読み取る簡単な例

PHP が無害な IP データベースを読み取る簡単な例

WBOY
WBOYオリジナル
2016-07-25 08:54:401450ブラウズ
  1. /*-------------------------------------- --- ------------------------
  2. ip2アドレス [qqwry.dat]
  3. ------------------------- ------ --------------------*/
  4. class ip {
  5. var $fh //IP データベース ファイル ハンドル
  6. var $first;最初のインデックス
  7. var $last; // 最後のインデックス
  8. var $total; // 総インデックス数
  9. // コンストラクター関数
  10. function __construct() {
  11. $this->fh = fopen('qqwry.dat', 'rb) '); / /qqwry.dat ファイル
  12. $this->first = $this->getLong4();
  13. $this->last = $this->getLong4();
  14. $this->total = ($this ->last - $this->first) / 7; //各インデックスは 7 バイトです
  15. }
  16. //IP 関数の正当性をチェックします checkIp($ip) {
  17. $arr =explode ('.', $ip);
  18. if(count($arr) !=4 ) {
  19. return false;
  20. } else {
  21. for ($i=0; $i if ($arr[$ i] <'0' || $arr[$i] > '255') {
  22. return false;
  23. }
  24. }
  25. }
  26. return true;
  27. }
  28. function getLong4() {
  29. //少し読み取ります - 4 バイトのエンディアン エンコーディングを長整数に変換します
  30. $result = unpack('Vlong', fread($this->fh, 4));
  31. return $result['long'];
  32. }
  33. function getLong3() {
  34. //リトルエンディアンエンコーディングの 3 バイトを読み取り、long 整数に変換します
  35. $result = unpack('Vlong', fread($this->fh, 3).chr(0 ));
  36. return $result['long'];
  37. }
  38. //情報を問い合わせる
  39. function getInfo($data = "") {
  40. $char = fread($this->fh, 1);
  41. while ( ord($char ) != 0) { //国と地域の情報は0で終わります
  42. $data .= $char;
  43. $char = fread($this->fh, 1);
  44. }
  45. return $data;
  46. } bbs. it-home.org
  47. //エリア情報を問い合わせる
  48. function getArea() {
  49. $byte = fread($this->fh, 1); //フラグbyte
  50. switch (ord($byte)) {
  51. case 0 : $area = ''; //エリア情報なし
  52. case 1: //エリアがリダイレクトされる
  53. fseek($this->fh, $this->getLong3());
  54. $area = $this- >getInfo(); Break;
  55. ケース 2: //エリアがリダイレクトされる
  56. fseek($this->fh, $this->getLong3());
  57. $area = $this- >getInfo(); Break;
  58. デフォルト: $area = $this->getInfo($byte); // エリアはリダイレクトされません
  59. }
  60. return $area;
  61. }
  62. function ip2addr($ip) {
  63. if(!$ this -> checkIp($ip)){
  64. return false;
  65. }
  66. $ip = Pack('N', intval(ip2long($ip)));
  67. //二分探索
  68. $ l = 0;
  69. $ r = $this->total;
  70. while($l $m = Floor(($l + $r) / 2) //中間インデックスを計算します
  71. fseek($this- >fh, $this->first + $m * 7);
  72. $beginip = strrev(fread($this->fh, 4)) //中間インデックスの開始 IP アドレス
  73. fseek($ this->fh, $this->getLong3());
  74. $endip = strrev(fread($this->fh, 4)) //中間インデックスの終了 IP アドレス
  75. if ($ ip $r = $m - 1;
  76. } else {
  77. if ($ip > $endip) { //ユーザーのIP がより大きい場合 中間インデックスの終了 IP アドレスが
  78. の場合 $l = $m + 1;
  79. } else { //ユーザー IP が中間インデックスの IP 範囲内の場合
  80. $findip = $this-> ;first + $m * 7;
  81. Break ;
  82. }
  83. }
  84. }
  85. //国と地域の情報をクエリ
  86. fseek($this->fh, $findip);
  87. $location['beginip'] = long2ip( $this->getLong4()); / /ユーザー IP 範囲の開始アドレス
  88. $offset = $this->getlong3();
  89. fseek($this->fh, $offset);
  90. $location[ 'endip'] = long2ip($this->getLong4()) //ユーザーIP範囲の終了アドレス
  91. $byte = fread($this->fh, 1) //フラグバイト
  92. スイッチ(ord) ($byte)) {
  93. case 1: //国と地域の両方の情報がリダイレクトされます
  94. $countryOffset = $this->getLong3() //アドレスをリダイレクトします
  95. fseek($this->fh, $countryOffset);
  96. $byte = fread($this ->fh, 1); //フラグバイト
  97. switch (ord($byte)) {
  98. case 2: //国情報は 2 回リダイレクトされます
  99. fseek($this->fh , $this->gt ;getLong3());
  100. $location['country'] = $this->getInfo();
  101. fseek($this->fh, $countryOffset + 4);
  102. $location[' area'] = $this->getArea();
  103. Break;
  104. デフォルト: //国情報は 2 回リダイレクトされません
  105. $location['country'] = $this->getInfo($byte);
  106. $location ['area '] = $this->getArea();
  107. break;
  108. }
  109. break;
  110. ケース2: //国情報はリダイレクトされます
  111. fseek($this->fh, $this->getLong3( )) ;
  112. $location['country'] = $this->getInfo();
  113. fseek($this->fh, $offset + 8);
  114. $location['area'] = $this-> ;getArea ();
  115. Break;
  116. デフォルト: //国情報はリダイレクトされません
  117. $location['country'] = $this->getInfo($byte);
  118. $location['area'] = $this- > ;getArea();
  119. ブレーク;
  120. }
  121. //gb2312 to utf-8 (情報がない場合に表示されるCZ88.NETを削除)
  122. foreach ($location as $k => $v) {
  123. $location[$k] = str_replace('CZ88.NET' , '',iconv('gb2312', 'utf-8', $v));
  124. }
  125. return $location;
  126. }
  127. //デストラクター
  128. function __destruct() {
  129. fclose($this->fh ) ;
  130. }
  131. }
  132. $ip = new ip();
  133. $addr = $ip -> ip2addr('IP アドレス');
  134. print_r($addr);
  135. ?>
コードをコピー


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。