Ec (2); & lt ;? Php tutorial *** @ date & nbsp; 2010.12.21 * @ author & nbsp; & nbsp; Wang Gang * @ email & nbsp; 37388 script ec (2); script
/**
* @ Date 2010.12.21
* @ Author Wang Gang
* @ Email 373882774@qq.com
* @ Qq 373882774
Note: the file header [offset of the first index (4 byte)] + [offset address of the last index (4 byte)] 8 bytes
Record area [end ip (4 byte)] + [region 1] + [Region 2] 4 bytes + Indefinite Length
Index Area [start ip (4 byte)] + [point to the record area offset address (3 byte)] 7 bytes
*/
Class iplocation {
Var $ fp;
Var $ firstip; // The offset address of the first ip Index
Var $ lastip; // the offset of the last ip Index
Var $ totalip; // total number of ip addresses
/*
| ----------------------------------------------------------------------------
| Constructor, initializing some variables
| ----------------------------------------------------------------------------
|
*/
Function iplocation ($ datfile = "qqwry. dat "){
$ This-> fp = fopen ($ datfile, 'rb') or die ("qqwry. dat does not exist. Please download the pure ip address data library, 'qqwry. dat 'put in the current directory "); // enable it in binary mode
$ This-> firstip = $ this-> get4b (); // The absolute offset address of the first ip Index
$ This-> lastip = $ this-> get4b (); // The absolute offset address of the last ip Index
$ This-> totalip = ($ this-> lastip-$ this-> firstip)/7; // The total number of ip addresses in the index area is a fixed length of 7 bytes, divide it by 7,
Register_shutdown_function (array ($ this, "closefp"); // to be compatible with versions earlier than php5, this class automatically closes the ip library without destructor.
}
/*
| ----------------------------------------------------------------------------
| Disable the ip address Library
| ----------------------------------------------------------------------------
|
*/
Function closefp (){
Fclose ($ this-> fp );
}
/*
| ----------------------------------------------------------------------------
| Read 4 bytes and decompress them to the long Mode
| ----------------------------------------------------------------------------
|
*/
Function get4b (){
$ Str = unpack ("v", fread ($ this-> fp, 4 ));
Return $ str [1];
}
/*
| ----------------------------------------------------------------------------
| Read the redirected offset address
| ----------------------------------------------------------------------------
|
*/
Function getoffset (){
$ Str = unpack ("v", fread ($ this-> fp, 3). chr (0 ));
Return $ str [1];
}
/*
| ----------------------------------------------------------------------------
| Read detailed ip address information
| ----------------------------------------------------------------------------
|
*/
Function getstr (){
$ Split = fread ($ this-> fp, 1 );
While (ord ($ split )! = 0 ){
$ Str. = $ split;
$ Split = fread ($ this-> fp, 1 );
}
Return $ str;
}
/*
| ----------------------------------------------------------------------------
| Convert an ip address through ip2long to an ipv4 internet address, compress it into the big-endian byte order, and use it to compare the ip address in the Index Area
| ----------------------------------------------------------------------------
|
*/
Function iptoint ($ ip ){
Return pack ("n", intval (ip2long ($ ip )));
}
/*
| ----------------------------------------------------------------------------
| Get address information
| ----------------------------------------------------------------------------
|
*/
Function readaddress (){
$ Now_offset = ftell ($ this-> fp); // obtain the current pointer address.
$ Flag = $ this-> getflag ();
Switch (ord ($ flag )){
Case 0:
$ Address = "";
Break;
Case 1:
Case 2:
Fseek ($ this-> fp, $ this-> getoffset ());
$ Address = $ this-> getstr ();
Break;
Default:
Fseek ($ this-> fp, $ now_offset );
$ Address = $ this-> getstr ();
Break;
}
Return $ address;
}
/*
| ----------------------------------------------------------------------------
| The get flag 1 or 2 is used to determine whether the address is redirected.
| ----------------------------------------------------------------------------
|
*/
Function getflag (){
Return fread ($ this-> fp, 1 );
}
/*
| ----------------------------------------------------------------------------
| Search for ip addresses in the index area using the Binary Search Method
| ----------------------------------------------------------------------------
|
*/
Function searchip ($ ip ){
$ Ip = gethostbyname ($ ip); // convert the domain name to an ip address
$ Ip_offset ["ip"] = $ ip;
$ Ip = $ this-> iptoint ($ ip); // convert the ip address into a growth integer.
$ Firstip = 0; // search upper boundary
$ Lastip = $ this-> totalip; // The bottom boundary of the search.
$ Ipoffset = $ this-> lastip; // The offset address initialized to the last IP address.
While ($ firstip <= $ lastip ){
$ I = floor ($ firstip + $ lastip)/2); // calculate the approximate intermediate record floor function to calculate the maximum integer of a given floating point number, to put it bluntly, four homes and five homes are also available.
Fseek ($ this-> fp, $ this-> firstip + $ I * 7); // locate the pointer to the intermediate record
$ Startip = strrev (fread ($ this-> fp, 4); // read the starting IP address in the current index area, and converts the byte order of its little-endian to the byte order of big-endian.
If ($ ip <$ startip ){
$ Lastip = $ I-1;
}
Else {
Fseek ($ this-> fp, $ this-> getoffset ());
$ Endip = strrev (fread ($ this-> fp, 4 ));
If ($ ip> $ endip ){
$ Firstip = $ I + 1;
}
Else {
$ Ip_offset ["offset"] = $ this-> firstip + $ I * 7;
Break;
}
}
}
Return $ ip_offset;
}
/*
| ----------------------------------------------------------------------------
| Obtain IP address details
| ----------------------------------------------------------------------------
|
*/
Function getaddress ($ ip ){
$ Ip_offset = $ this-> searchip ($ ip); // obtain the absolute address of the ip in the index area.
$ Ipoffset = $ ip_offset ["offset"];
$ Address ["ip"] = $ ip_offset ["ip"];
Fseek ($ this-> fp, $ ipoffset); // locate the Index Area
$ Address ["startip"] = long2ip ($ this-> get4b (); // start ip address in the Index Area
$ Address_offset = $ this-> getoffset (); // obtains the offset of the ip address in the ip record area in the index area.
Fseek ($ this-> fp, $ address_offset); // locate to the record area
$ Address ["endip"] = long2ip ($ this-> get4b (); // end ip address in the record area
$ Flag = $ this-> getflag (); // read the flag byte
Switch (ord ($ flag )){
Case 1: // region 1 Region 2 are redirected
$ Address_offset = $ this-> getoffset (); // read the redirection address
Fseek ($ this-> fp, $ address_offset); // locate the pointer to the redirected address
$ Flag = $ this-> getflag (); // read the flag byte
Switch (ord ($ flag )){
Case 2: // region 1 is redirected again,
Fseek ($ this-> fp, $ this-> getoffset ());
$ Address ["area1"] = $ this-> getstr ();
Fseek ($ this-> fp, $ address_offset + 4); // 4 bytes
$ Address ["area2"] = $ this-> readaddress (); // Region 2 may be redirected, but may not
Break;
Default: // region 1, Region 2 are not redirected
Fseek ($ this-> fp, $ address_offset); // locate the pointer to the redirected address
$ Address ["area1"] = $ this-> getstr ();
$ Address ["area2"] = $ this-> readaddress ();
Break;
}
Break;
Case 2: // region 1 redirection Region 2 No redirection
$ Address1_offset = $ this-> getoffset (); // read the redirection address
Fseek ($ this-> fp, $ address1_offset );
$ Address ["area1"] = $ this-> getstr ();
Fseek ($ this-> fp, $ address_offset + 8 );
$ Address ["area2"] = $ this-> readaddress ();
Break;
Default: // region 1 Region 2 is not redirected
Fseek ($ this-> fp, $ address_offset + 4 );
$ Address ["area1"] = $ this-> getstr ();
$ Address ["area2"] = $ this-> readaddress ();
Break;
}
// * Filter useless data
If (strpos ($ address ["area1"], "cz88.net ")! = False ){
$ Address ["area1"] = "unknown ";
}
If (strpos ($ address ["area2"], "cz88.net ")! = False ){
$ Address ["area2"] = "";
}
Return $ address;
}
}
/* Usage :*/
$ Ip = new iplocation ("qqwry. dat ");
$ Address = $ ip-> getaddress ("221.231.102.100 ");
// $ Address = $ ip-> getaddress (www.111cn.net );
Echo'
';
print_r($address);
?>