-
- /*----------------------------------------- ----------
- ip2address [qqwry.dat]
- --------------------------------- --------------------*/
- class ip {
- var $fh; //IP database file handle
- var $first; //First index
- var $last; //The 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; //Each index is 7 bytes
- }
- //Check the legality of the IP
- 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 little -Convert 4 bytes of endian encoding to long integer
- $result = unpack('Vlong', fread($this->fh, 4));
- return $result['long'];
- }
- function getLong3() {
- //Read the 3 bytes of little-endian encoding and convert it into a long integer
- $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 and region information ends with 0
- $data .= $char;
- $char = fread($this->fh, 1);
- }
- return $data;
- } bbs.it-home.org
- //Query area information
- function getArea() {
- $byte = fread($this->fh, 1); //Flag byte
- switch (ord($byte)) {
- case 0: $area = ''; break; //There is no area information
- case 1: //The area is redirected
- fseek($this->fh, $this->getLong3());
- $ area = $this->getInfo(); break;
- case 2: //Area is redirected
- fseek($this->fh, $this->getLong3());
- $area = $this- >getInfo(); break;
- default: $area = $this->getInfo($byte); break; //The area is not redirected
- }
- return $area;
- }
- function ip2addr($ip) {
- if(!$this -> checkIp($ip)){
- return false;
- }
- $ip = pack('N', intval(ip2long($ip)));
- //Binary search
- $ l = 0;
- $r = $this->total;
- while($l <= $r) {
- $m = floor(($l + $r) / 2); //Calculate the intermediate index
- fseek($this->fh, $this->first + $m * 7);
- $beginip = strrev(fread($this->fh, 4)); //The starting IP address of the intermediate index
- fseek($this->fh, $this->getLong3());
- $endip = strrev(fread($this->fh, 4)); //End IP address of the intermediate index
- if ($ ip < $beginip) { //When the user's IP is less than the starting IP address of the intermediate index
- $r = $m - 1;
- } else {
- if ($ip > $endip) { //The user's IP is greater than When the ending IP address of the intermediate index is
- $l = $m + 1;
- } else { //When the user IP is within the IP range of the intermediate index
- $findip = $this->first + $m * 7;
- break ;
- }
- }
- }
- //Query country and region information
- fseek($this->fh, $findip);
- $location['beginip'] = long2ip($this->getLong4()); / /Start address of the user IP range
- $offset = $this->getlong3();
- fseek($this->fh, $offset);
- $location['endip'] = long2ip($this-> ;getLong4()); //End address of the user IP range
- $byte = fread($this->fh, 1); //Flag byte
- switch (ord($byte)) {
- case 1: //Both country and region information are 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 twice
- 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 twice
- $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 (remove CZ88.NET displayed when there is no information)
- 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);
- ?>
Copy code
|