<?php
/*--------------------------------------------------
ip2address [Qqwry.dat]
--------------------------------------------------*/
Class IP {
var $fh; IP database file handle
var $first; First Index
var $last; Last index
var $total; Total indexes
Constructors
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 legality
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 4 bytes of Little-endian encoded into long integer numbers
$result = Unpack (' Vlong ', fread ($this->fh, 4));
return $result [' Long '];
}
function GetLong3 () {
Read 3 bytes of Little-endian encoded into long integer numbers
$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;
}
Query Area Information
function Getarea () {
$byte = Fread ($this->fh, 1); Flag byte
Switch (ord ($byte)) {
Case 0: $area = '; Break No regional information
Case 1://Area redirected
Fseek ($this->fh, $this->getlong3 ());
$area = $this->getinfo (); Break
Case 2://Area redirected
Fseek ($this->fh, $this->getlong3 ());
$area = $this->getinfo (); Break
Default: $area = $this->getinfo ($byte); Break Area 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 an intermediate index
Fseek ($this->fh, $this->first + $m * 7);
$beginip = Strrev (fread ($this->fh, 4)); 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 the end IP address of the intermediate index
$l = $m + 1;
} else {//User IP is within the IP range of the intermediate index
$findip = $this->first + $m * 7;
Break
}
}
}
Find information about the country area
Fseek ($this->fh, $findip);
$location [' beginip '] = Long2ip ($this->getlong4 ()); Start address of the range where the user IP resides
$offset = $this->getlong3 ();
Fseek ($this->fh, $offset);
$location [' endip '] = Long2ip ($this->getlong4 ()); End address of User IP range
$byte = Fread ($this->fh, 1); Flag byte
Switch (ord ($byte)) {
Case 1://country and region information is redirected
$countryOffset = $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 not redirected by two times
$location [' country '] = $this->getinfo ($byte);
$location [' area '] = $this->getarea ();
Break
}
Break
Case 2://Country Information redirected
Fseek ($this->fh, $this->getlong3 ());
$location [' country '] = $this->getinfo ();
Fseek ($this->fh, $offset + 8);
$location [' area '] = $this->getarea ();
Break
Default://country Information not redirected
$location [' country '] = $this->getinfo ($byte);
$location [' area '] = $this->getarea ();
Break
}
gb2312 to Utf-8 (cz88.net that is displayed when no information is removed)
foreach ($location as $k => $v) {
$location [$k] = Str_replace (' CZ88. NET ', ', Iconv (' gb2312 ', ' utf-8 ', $v));
}
return $location;
}
destructor
function __destruct () {
Fclose ($this->fh);
}
}
$ip = new IP ();
$addr = $ip-> ip2addr (' IP address ');
Print_r ($ADDR);
?>