Copy CodeThe code is as follows:
/*--------------------------------------------------
ip2address [Qqwry.dat]
--------------------------------------------------*/
Class IP {
var $fh; IP database file handle
var $first; First Index
var $last; Last index
var $total; Total indexes
constructor function
function __construct () {
$this->fh = fopen (' Qqwry.dat ', ' RB '); Qqwry.dat file
$this->first = $this->getlong4 ();
$this->last = $this->getlong4 ();
$this->total = ($this->last-$this->first)/7; 7 bytes per index
}
Check IP legitimacy
function Checkip ($IP) {
$arr = Explode ('. ', $IP);
if (count ($arr)!=4) {
return false;
} else {
for ($i =0; $i < 4; $i + +) {
if ($arr [$i] < ' 0 ' | | $arr [$i] > ' 255 ') {
return false;
}
}
}
return true;
}
function GetLong4 () {
Read the Little-endian encoded 4 bytes into a long integer number
$result = Unpack (' Vlong ', fread ($this->fh, 4));
return $result [' Long '];
}
function GetLong3 () {
Read the Little-endian encoded 3 bytes into a long integer number
$result = Unpack (' Vlong ', fread ($this->fh, 3). chr (0));
return $result [' Long '];
}
Query information
function GetInfo ($data = "") {
$char = Fread ($this->fh, 1);
while (ORD ($char)! = 0) {//Country area information ends with 0
$data. = $char;
$char = Fread ($this->fh, 1);
}
return $data;
}
Find area Information
function Getarea () {
$byte = Fread ($this->fh, 1); Flag byte
Switch (ord ($byte)) {
Case 0: $area = '; Break No area information
Case 1://Region redirected
Fseek ($this->fh, $this->getlong3 ());
$area = $this->getinfo (); Break
Case 2://Region redirected
Fseek ($this->fh, $this->getlong3 ());
$area = $this->getinfo (); Break
Default: $area = $this->getinfo ($byte); Break Region is not redirected
}
return $area;
}
function Ip2addr ($IP) {
if (! $this, Checkip ($IP)) {
return false;
}
$ip = Pack (' N ', Intval (Ip2long ($IP)));
Two-point Search
$l = 0;
$r = $this->total;
while ($l <= $r) {
$m = Floor (($l + $r)/2); Calculate Intermediate Index
Fseek ($this->fh, $this->first + $m * 7);
$beginip = Strrev (fread ($this->fh, 4)); The start IP address of the intermediate index
Fseek ($this->fh, $this->getlong3 ());
$endip = Strrev (fread ($this->fh, 4)); End IP address of intermediate index
If ($ip < $beginip) {//user's IP is less than the start IP address of the intermediate index
$r = $m-1;
} else {
if ($ip > $endip) {//user's IP is greater than intermediate index End IP Address
$l = $m + 1;
} else {//User IP is within the IP range of the intermediate index
$findip = $this->first + $m * 7;
break;
}
}
}
//Query Country area information
Fseek ($this->fh, $findip);
$location [' beginip '] = Long2ip ($this->getlong4 ());// The start address of the range where the user IP is located
$offset = $this->getlong3 ();
Fseek ($this->fh, $offset);
$location [' endip '] = Long2ip ($ This->getlong4 ()); End address of the range where the user IP is located
$byte = fread ($this->fh, 1);//Flag Byte
Switch (ORD ($byte)) {
Case 1://country and region information are redirected
$count Ryoffset = $this->getlong3 (); REDIRECT Address
Fseek ($this->fh, $countryOffset);
$byte = Fread ($this->fh, 1);//Flag Byte
Switch (ORD ($byte)) {
Case 2://Country information is redirected two times
Fseek ($this->fh, $this->getlong3 ()),
$location [' country '] = $this->getinfo ( );
Fseek ($this->fh, $countryOffset + 4);
$location [' area '] = $this->getarea ();
break;
Default://Country information is not redirected two times
$location [' country '] = $this->getinfo ($byte);
$location [' area '] = $this Getarea ();
break;
}
Break;
Case 2://country information is redirected
Fseek ($this->fh, $this->getlong3 ());
$location [' country '] = $this->getinfo ();
Fseek ($this->fh, $offset + 8);
$location [' area '] = $this->getarea ();
Break
Default://Country information is not redirected
$location [' country '] = $this->getinfo ($byte);
$location [' area '] = $this->getarea ();
Break
}
gb2312 to Utf-8 (cz88.net displayed when no information is removed)
foreach ($location as $k = = $v) {
$location [$k] = Str_replace (' CZ88. NET ', ', Iconv (' gb2312 ', ' utf-8 ', $v));
}
return $location;
}
Destructors
function __destruct () {
Fclose ($this->fh);
}
}
$ip = new IP ();
$ADDR = ip2addr (' IP address '), $ip
Print_r ($ADDR);
?>