Use QQWry. Dat for efficient IP address retrieval

Source: Internet
Author: User
Tags ip location information
According to the detailed description of the pure IP database format in LumaQQ developer documentation, I have compiled a PHP class for querying IP address region information. During the compilation process, we found that the description of the record area in the explanation of the pure IP database format was not comprehensive, but it was not very large, so I didn't need to write a description of the pure IP database format, if you are interested, read the IP address

According to the detailed description of the pure IP database format in LumaQQ developer documentation, I have compiled a PHP class for querying IP address region information. During the compilation process, we found that the description of the record area in the explanation of the pure IP database format was not comprehensive, but it was not very large, so I didn't need to write a description of the pure IP database format, if you are interested, you can read the following code. The code contains detailed comments, which can be easily understood.

After creating an instance of this class, the instance stores the opened file pointer and some information required for query. you do not need to re-open the file during each query until the execution of the page ends, the opened file will be closed automatically. In this way. When performing multiple queries on a page, the efficiency is very high. In addition, this type can not only directly query IP addresses, but also automatically resolve domain names to IP addresses for query.

The following is the program code:

       
        Fp, 4); return $ result ['long'];} /*** return the number of long integers of the three bytes read ** @ access private * @ return int */function getlong3 () {// convert the three bytes of the read little-endian encoding into the number of long integers $ result = unpack ('vlong', fread ($ this-> fp, 3 ). chr (0); return $ result ['long'];} /*** return the compressed ip address ** @ access private * @ param string $ ip * @ return string */function packip ($ ip) {// Convert the IP address to a long integer. If an IP address error occurs in PHP5, False is returned. // intval converts Flase to an integer-1, and then compress it into a big-endian encoded string r. Eturn pack ('N', intval (ip2long ($ ip )));} /*** return the read string ** @ access private * @ param string $ data * @ return string */function getstring ($ data = "") {$ char = fread ($ this-> fp, 1); while (ord ($ char)> 0) {// The string is saved in C format, end $ data with \ 0. = $ char; // connect the read characters to the given string $ char = fread ($ this-> fp, 1);} return $ data ;} /*** return region information ** @ access private * @ return string */function getarea () {$ byte = fread ($ this-> fp, 1 ); // Mark byte switch (Ord ($ byte) {case 0: // no region information $ area = ""; break; case 1: case 2: // indicates that the byte is 1 or 2, fseek ($ this-> fp, $ this-> getlong3 (); $ area = $ this-> getstring (); break; default: // otherwise, the region information is not redirected $ area = $ this-> getstring ($ byte); break;} return $ area ;} /*** return region information based on the given IP address or domain name ** @ access public * @ param string $ ip * @ return array */function getlocation ($ ip) {if (! $ This-> fp) return null; // if the data file is not properly opened, a blank $ location ['IP'] = gethostbyname ($ ip) is returned ); // Convert the entered domain name to an ip address $ ip = $ this-> packip ($ location ['IP']); // Convert the entered IP address to a comparable IP address // an invalid IP address is converted to 255.255.255.255.255 // You can search for $ l = 0; // search for the bottom boundary $ u = $ this-> totalip; // search for the top boundary $ findip = $ this-> lastip; // if not found, return the last IP record (QQWry. dat version information) while ($ l <= $ u) {// when the boundary is smaller than the bottom boundary, the query fails $ I = floor ($ l $ u) /2); // calculate the approximate intermediate record fseek ($ this-> fp, $ thi S-> firstip $ I * 7); $ beginip = strrev (fread ($ this-> fp, 4 )); // Obtain the starting IP address of the intermediate record. // The strrev function is used to convert the compressed IP address of little-endian to the format of big-endian. // This function is used for comparison. If ($ ip <$ beginip) {// when the user's IP address is smaller than the starting ip address of the intermediate record, $ u = $ I-1; // change the upper boundary of the search to an intermediate record minus one} else {fseek ($ this-> fp, $ this-> getlong3 ()); $ endip = strrev (fread ($ this-> fp, 4); // Obtain the end ip address of the intermediate record if ($ ip> $ endip) {// when the user's IP address is greater than the end IP address of the intermediate record $ l = $ I 1; // change the bottom boundary of the search to an intermediate record plus} else {// when the user's IP address is within the IP range of the intermediate record $ findip = $ this-> firstip $ I * 7; break; // indicates finding the result and exiting the loop }}// obtain the IP location information fseek ($ this-> fp, $ findip ); $ location ['beginip'] = long2i P ($ this-> getlong (); // start address of the user's IP address range $ offset = $ this-> getlong3 (); fseek ($ this-> fp, $ offset); $ location ['enabled'] = long2ip ($ this-> getlong ()); // end address of the user's IP address range $ byte = fread ($ this-> fp, 1); // Mark byte switch (ord ($ byte) {case 1: // The flag byte is 1, indicating that the country and region information is redirected at the same time $ countryOffset = $ this-> getlong3 (); // redirect address fseek ($ this-> fp, $ countryOffset); $ byte = fread ($ this-> fp, 1); // Mark byte switch (ord ($ byte) {case 2: // The flag byte is 2, indicating Country Information is redirected to fseek ($ this-> fp, $ this-> getlong3 (); $ location ['country'] = $ this-> getstring (); fseek ($ this-> fp, $ countryOffset 4); $ location ['region'] = $ this-> getarea (); break; default: // otherwise, the country information is not Redirected. $ location ['country'] = $ this-> getstring ($ byte); $ location ['region'] = $ this-> getarea (); break;} break; case 2: // The flag byte is 2, indicating that the country information is redirected to fseek ($ this-> fp, $ this-> getlong3 ()); $ location ['country'] = $ this-> getstring (); fseek ($ This-> fp, $ offset 8); $ location ['region'] = $ this-> getarea (); break; default: // otherwise, the country information is not Redirected. $ location ['country'] = $ this-> getstring ($ byte); $ location ['region'] = $ this-> getarea (); break;} if ($ location ['country'] = "CZ88.NET") {// CZ88.NET indicates no valid information. $ location ['country'] = "unknown ";} if ($ location ['region'] = "CZ88.NET") {$ location ['region'] = "" ;}return $ location ;}/ *** constructor, open QQWry. dat file and initialize information in the class ** @ 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 the destructor, execute register_shutdown_function (array (& $ this, '_ iplocation') ;}/ *** destructor at the end of program execution, used to automatically close opened files after Page execution ends. **/Function _ IpLocation () {fclose ($ this-> fp) ;}}?>
       

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.