首頁 後端開發 php教程 利用QQWry.Dat实现IP地址高效检索_PHP

利用QQWry.Dat实现IP地址高效检索_PHP

Jun 01, 2016 pm 12:30 PM
ip 使用 地址 實現 檢索 高效率

IP地址

根据 LumaQQ 开发者文档中的纯真 IP 数据库格式详解,我编写了一个 PHP 的查询 IP 所在地区信息的类。在编写过程中发现纯真 IP 数据库格式详解中关于记录区的描述不是很全面,不过出入也不是很大,所以我没必要再写一份纯真 IP 数据库的格式说明了,大家感兴趣的话,读一读下面的代码应该就能看出来了。代码中加了很详细的注释,应该很容易读懂的。

在创建这个类的一个实例后,实例中就保存了打开的文件指针和一些查询需要的信息,每次查询时不需要重新打开文件,直到页面执行结束后,打开的文件才会自动关闭。这样。在一个页面内进行多次查询时,效率是很高的。并且此类不仅可以直接查询 IP,还可以自动将域名解析为 IP 进行查询。

下面是程序代码:

<ccid_code><?php /**

* @author 马秉尧

*/



class IpLocation {



/**

* QQWry.Dat文件指针

* @var resource

*/



var $fp;



/**

* 第一条IP记录的偏移地址

*

* @var int

*/



var $firstip;



/**

* 最后一条IP记录的偏移地址

*

* @var int

*/



var $lastip;



/**

* IP记录的总条数(不包含版本信息记录)

*

* @var int

*/



var $totalip;



/**

* 返回读取的长整型数

*

* @access private

* @return int

*/



function getlong() {



//将读取的little-endian编码的4个字节转化为长整型数



$result = unpack('Vlong', fread($this->fp, 4));



return $result['long'];



}



/**

* 返回读取的3个字节的长整型数

*

* @access private

* @return int

*/



function getlong3() {



//将读取的little-endian编码的3个字节转化为长整型数



$result = unpack('Vlong', fread($this->fp, 3).chr(0));



return $result['long'];



}



/**

* 返回压缩后可进行比较的IP地址

*

* @access private

* @param string $ip

* @return string

*/



function packip($ip) {



// 将IP地址转化为长整型数,如果在PHP5中,IP地址错误,则返回False,



// 这时intval将Flase转化为整数-1,之后压缩成big-endian编码的字符串



return pack('N', intval(ip2long($ip)));



}



/**

* 返回读取的字符串

*

* @access private

* @param string $data

* @return string

*/



function getstring($data = "") {



$char = fread($this->fp, 1);



while (ord($char) > 0) { // 字符串按照C格式保存,以\0结束



$data .= $char; // 将读取的字符连接到给定字符串之后



$char = fread($this->fp, 1);



}



return $data;



}



/**

* 返回地区信息

*

* @access private

* @return string

*/



function getarea() {



$byte = fread($this->fp, 1); // 标志字节



switch (ord($byte)) {



case 0: // 没有区域信息



$area = "";



break;



case 1:



case 2: // 标志字节为1或2,表示区域信息被重定向



fseek($this->fp, $this->getlong3());



$area = $this->getstring();



break;



default: // 否则,表示区域信息没有被重定向



$area = $this->getstring($byte);



break;



}



return $area;



}



/**

* 根据所给 IP 地址或域名返回所在地区信息

*

* @access public

* @param string $ip

* @return array

*/



function getlocation($ip) {



if (!$this->fp) return null; // 如果数据文件没有被正确打开,则直接返回空



$location['ip'] = gethostbyname($ip); // 将输入的域名转化为IP地址



$ip = $this->packip($location['ip']); // 将输入的IP地址转化为可比较的IP地址



// 不合法的IP地址会被转化为255.255.255.255



// 对分搜索



$l = 0; // 搜索的下边界



$u = $this->totalip; // 搜索的上边界



$findip = $this->lastip; // 如果没有找到就返回最后一条IP记录(QQWry.Dat的版本信息)



while ($l fp, $this->firstip   $i * 7);



$beginip = strrev(fread($this->fp, 4)); // 获取中间记录的开始IP地址



// strrev函数在这里的作用是将little-endian的压缩IP地址转化为big-endian的格式



// 以便用于比较,后面相同。



if ($ip fp, $this->getlong3());



$endip = strrev(fread($this->fp, 4)); // 获取中间记录的结束IP地址



if ($ip > $endip) { // 用户的IP大于中间记录的结束IP地址时



$l = $i   1; // 将搜索的下边界修改为中间记录加一



}



else { // 用户的IP在中间记录的IP范围内时



$findip = $this->firstip   $i * 7;



break; // 则表示找到结果,退出循环



}



}



}







//获取查找到的IP地理位置信息



fseek($this->fp, $findip);



$location['beginip'] = long2ip($this->getlong()); // 用户IP所在范围的开始地址



$offset = $this->getlong3();



fseek($this->fp, $offset);



$location['endip'] = long2ip($this->getlong()); // 用户IP所在范围的结束地址



$byte = fread($this->fp, 1); // 标志字节



switch (ord($byte)) {



case 1: // 标志字节为1,表示国家和区域信息都被同时重定向



$countryOffset = $this->getlong3(); // 重定向地址



fseek($this->fp, $countryOffset);



$byte = fread($this->fp, 1); // 标志字节



switch (ord($byte)) {



case 2: // 标志字节为2,表示国家信息又被重定向



fseek($this->fp, $this->getlong3());



$location['country'] = $this->getstring();



fseek($this->fp, $countryOffset   4);



$location['area'] = $this->getarea();



break;



default: // 否则,表示国家信息没有被重定向



$location['country'] = $this->getstring($byte);



$location['area'] = $this->getarea();



break;



}



break;



case 2: // 标志字节为2,表示国家信息被重定向



fseek($this->fp, $this->getlong3());



$location['country'] = $this->getstring();



fseek($this->fp, $offset   8);



$location['area'] = $this->getarea();



break;



default: // 否则,表示国家信息没有被重定向



$location['country'] = $this->getstring($byte);



$location['area'] = $this->getarea();



break;



}



if ($location['country'] == " CZ88.NET") { // CZ88.NET表示没有有效信息



$location['country'] = "未知";



}



if ($location['area'] == " CZ88.NET") {



$location['area'] = "";



}



return $location;



}



/**

* 构造函数,打开 QQWry.Dat 文件并初始化类中的信息

*

* @param string $filename

* @return IpLocation

*/



function IpLocation($filename = "QQWry.Dat") {



if (($this->fp = @fopen($filename, 'rb')) !== false) {



$this->firstip = $this->getlong();



$this->lastip = $this->getlong();



$this->totalip = ($this->lastip - $this->firstip) / 7;



//注册析构函数,使其在程序执行结束时执行



register_shutdown_function(array(&$this, '_IpLocation'));



}



}



/**

* 析构函数,用于在页面执行结束后自动关闭打开的文件。

*

*/



function _IpLocation() {



fclose($this->fp);



}



}



?></ccid_code>
登入後複製
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1664
14
CakePHP 教程
1423
52
Laravel 教程
1317
25
PHP教程
1268
29
C# 教程
1247
24
華為手機如何實現雙微信登入? 華為手機如何實現雙微信登入? Mar 24, 2024 am 11:27 AM

華為手機如何實現雙微信登入?隨著社群媒體的興起,微信已成為人們日常生活中不可或缺的溝通工具之一。然而,許多人可能會遇到一個問題:在同一部手機上同時登入多個微信帳號。對於華為手機用戶來說,實現雙微信登入並不困難,本文將介紹華為手機如何實現雙微信登入的方法。首先,華為手機自帶的EMUI系統提供了一個很方便的功能-應用程式雙開。透過應用程式雙開功能,用戶可以在手機上同

PHP程式設計指南:實作斐波那契數列的方法 PHP程式設計指南:實作斐波那契數列的方法 Mar 20, 2024 pm 04:54 PM

程式語言PHP是一種用於Web開發的強大工具,能夠支援多種不同的程式設計邏輯和演算法。其中,實作斐波那契數列是一個常見且經典的程式設計問題。在這篇文章中,將介紹如何使用PHP程式語言來實作斐波那契數列的方法,並附上具體的程式碼範例。斐波那契數列是一個數學上的序列,其定義如下:數列的第一個和第二個元素為1,從第三個元素開始,每個元素的值等於前兩個元素的和。數列的前幾元

美團地址在哪裡改?美團地址修改教學! 美團地址在哪裡改?美團地址修改教學! Mar 15, 2024 pm 04:07 PM

一、美團地址在哪裡改?美團地址修改教學!方法(一)1.進入美團我的頁面,點選設定。 2.選擇個人資訊。 3.再點選收貨地址。 4.最後選擇要修改的地址,點選地址右側的筆圖標,修改即可。方法(二)1.在美團app首頁,點選外賣,進入後點選更多功能。 2.在更多介面,點選管理地址。 3.在我的收貨地址介面,選擇編輯。 4.依需求一一修改,最後點選儲存地址即可。

如何在華為手機上實現微信分身功能 如何在華為手機上實現微信分身功能 Mar 24, 2024 pm 06:03 PM

如何在華為手機上實現微信分身功能隨著社群軟體的普及和人們對隱私安全的日益重視,微信分身功能逐漸成為人們關注的焦點。微信分身功能可以幫助使用者在同一台手機上同時登入多個微信帳號,方便管理和使用。在華為手機上實現微信分身功能並不困難,只需要按照以下步驟操作即可。第一步:確保手機系統版本和微信版本符合要求首先,確保你的華為手機系統版本已更新至最新版本,以及微信App

手機如何查看MAC位址(簡單操作讓你輕鬆取得裝置的MAC位址) 手機如何查看MAC位址(簡單操作讓你輕鬆取得裝置的MAC位址) Apr 19, 2024 pm 06:19 PM

我們可能需要查看手機的MAC位址、在一些特定的情況下,例如設定無線網路過濾或進行裝置管理。本文將教你如何透過手機輕鬆取得設備的MAC位址。 1.什麼是MAC位址2.手機系統:Android和iOS3.Android系統中查看MAC位址的方法4.iOS系統中查看MAC位址的方法5.使用設備管理應用程式查看MAC位址6.透過無線路由器查看連接設備的MAC位址7.透過第三方應用程式查看MAC位址8.透過手機設定中的開發者選項查看MAC位址9.使用網路分析工具查看MAC位址10.透過命令列方式查看MAC位址

掌握Golang如何實現遊戲開發的可能性 掌握Golang如何實現遊戲開發的可能性 Mar 16, 2024 pm 12:57 PM

在現今的軟體開發領域中,Golang(Go語言)作為一種高效、簡潔、並發性強的程式語言,越來越受到開發者的青睞。其豐富的標準庫和高效的並發特性使它成為遊戲開發領域的一個備受關注的選擇。本文將探討如何利用Golang來實現遊戲開發,並透過具體的程式碼範例來展示其強大的可能性。 1.Golang在遊戲開發中的優勢作為靜態類型語言,Golang正在建構大型遊戲系統

PHP遊戲需求實作指南 PHP遊戲需求實作指南 Mar 11, 2024 am 08:45 AM

PHP遊戲需求實現指南隨著網路的普及和發展,網頁遊戲的市場也越來越火爆。許多開發者希望利用PHP語言來開發自己的網頁遊戲,而實現遊戲需求是其中一個關鍵步驟。本文將介紹如何利用PHP語言來實現常見的遊戲需求,並提供具體的程式碼範例。 1.創造遊戲角色在網頁遊戲中,遊戲角色是非常重要的元素。我們需要定義遊戲角色的屬性,例如姓名、等級、經驗值等,並提供方法來操作這些

C盤空間告急! 5種高效率清理方法大揭密! C盤空間告急! 5種高效率清理方法大揭密! Mar 26, 2024 am 08:51 AM

C盤空間告急! 5種高效率清理方法大揭密!在使用電腦的過程中,不少用戶會遇到C盤空間告急的情況,尤其是在儲存或安裝大量檔案後,C碟的可用空間會迅速減少,進而影響電腦效能和運作速度。此時,對C盤進行清理是十分必要的。那麼,該如何有效率地清理C盤呢?接下來,本文將揭示5種高效率的清理方法,幫助您輕鬆解決C盤空間抱怨的問題。一、清理臨時檔案臨時檔案是電腦在運作時產生的一些暫

See all articles