看到有人分享了一个,那就分享个经典的利用纯真IP数据库查询吧,相信有很多人都见过甚至用过了这个代码。不过可能不知道,这个代码其实是从一个PECL的C++代码改过来的。PHP代码/*++++++++++++++++++++++++++++++++++++
程序名称:IP解析程序
程序功能:基于QQ的二进制数据库QQWry.Dat
程序作者:strongc
使用方法:
请将文件 QQWry.Dat 置于当前目录中
或者可以用修改
define('__QQWRY__' , dirname(__FILE__).".\QQWry.Dat");
语句自定义QQWry.Dat路径
#实例+++++++++++++++++++++++++++++++
$ip="202.201.48.1";
$QQWry=new QQWry;
$ifErr=$QQWry->QQWry($ip);
echo "$QQWry->Country$QQWry->Local";
+++++++++++++++++++++++++++++++++++++*/
define('__QQWRY__' , dirname(__FILE__).".\QQWry.Dat");
class QQWry
{
var $StartIP = 0;
var $EndIP = 0;
var $Country = '';
var $Local = '';
var $CountryFlag = 0; // 标识 Country位置
// 0x01,随后3字节为Country偏移,没有Local
// 0x02,随后3字节为Country偏移,接着是Local
// 其他,Country,Local,Local有类似的压缩。可能多重引用。
var $fp;
var $FirstStartIp = 0;
var $LastStartIp = 0;
var $EndIpOff = 0;
function getStartIp($RecNo)
{
$offset = $this->FirstStartIp + $RecNo * 7;
@fseek($this->fp, $offset, SEEK_SET);
$buf = fread($this->fp, 7);
$this->EndIpOff = ord($buf[4]) + (ord($buf[5]) * 256) + (ord($buf[6]) * 256 * 256);
$this->StartIp = ord($buf[0]) + (ord($buf[1]) * 256) + (ord($buf[2]) * 256 * 256) + (ord($buf[3]) * 256 * 256 * 256);
return $this->StartIp;
}
function getEndIp()
{
@fseek($this->fp, $this->EndIpOff, SEEK_SET);
$buf = fread($this->fp, 5);
$this->EndIp = ord($buf[0]) + (ord($buf[1]) * 256) + (ord($buf[2]) * 256 * 256) + (ord($buf[3]) * 256 * 256 * 256);
$this->CountryFlag = ord($buf[4]);
return $this->EndIp;
}
function getCountry()
{
switch($this->CountryFlag)
{
case 1:
case 2:
$this->Country = $this->getFlagStr($this->EndIpOff + 4);
$this->Local = (1 == $this->CountryFlag) ? '' : $this->getFlagStr($this->EndIpOff + 8);
break ;
default:
$this->Country = $this->getFlagStr($this->EndIpOff + 4);
$this->Local = $this->getFlagStr(ftell($this->fp));
}
}
function getFlagStr($offset)
{
$flag = 0;
while(1)
{
@fseek($this->fp, $offset, SEEK_SET);
$flag = ord(fgetc($this->fp));
if($flag == 1 || $flag == 2)
{
$buf = fread($this->fp, 3);
if($flag == 2)
{
$this->CountryFlag = 2;
$this->EndIpOff = $offset - 4;
}
$offset = ord($buf[0]) + (ord($buf[1]) * 256) + (ord($buf[2]) * 256 * 256);
}
else
break;
}
if($offset < 12) return '';
@fseek($this->fp, $offset, SEEK_SET);
return $this->getStr();
}
function getStr()
{
$str = '';
while(1)
{
$c = fgetc($this->fp);
if(ord($c[0]) == 0) break;
$str .= $c;
}
return $str;
}
function QQwry($dotip = '')
{
if(!$dotip) return;
if(ereg("^(127)", $dotip))
{
$this->Country = '本地网络';
return;
}
else if(ereg("^(192)", $dotip))
{
$this->Country = '局域网';
return;
}
$nRet;
$ip = $this->IpToInt($dotip);
$this->fp = fopen(__QQWRY__, "rb");
if($this->fp == NULL)
{
$szLocal = "OpenFileError";
return 1;
}
@fseek($this->fp, 0, SEEK_SET);
$buf = fread($this->fp, 8);
$this->FirstStartIp = ord($buf[0]) + (ord($buf[1]) * 256) + (ord($buf[2]) * 256 * 256) + (ord($buf[3]) * 256 * 256 * 256);
$this->LastStartIp = ord($buf[4]) + (ord($buf[5]) * 256) + (ord($buf[6]) * 256 * 256) + (ord($buf[7]) * 256 * 256 * 256);
$RecordCount = floor(($this->LastStartIp - $this->FirstStartIp) / 7);
if($RecordCount Country = "FileDataError";
fclose($this->fp) ;
return 2 ;
}
$RangB = 0;
$RangE = $RecordCount;
// Match ...
while($RangB < $RangE - 1)
{
$RecNo = floor(($RangB + $RangE) / 2);
$this->getStartIp($RecNo) ;
if($ip == $this->StartIp)
{
$RangB = $RecNo;
break;
}
if($ip > $this->StartIp) $RangB = $RecNo;
else $RangE = $RecNo;
}
$this->getStartIp($RangB);
$this->getEndIp();
if(($this->StartIp EndIp >= $ip))
{
$this->getCountry();
}
else
{
$this->Country = '未知';
$this->Local = '';
}
fclose($this->fp);
}
function IpToInt($Ip)
{
$array = explode('.', $Ip);
$Int = ($array[0] * 256 * 256 * 256) + ($array[1] * 256 * 256) + ($array[2] * 256) + $array[3];
return $Int;
}
}
2.[代码][PHP]代码$ip = "202.201.48.1";
$QQWry = new QQWry;
$ifErr = $QQWry->QQWry($ip);
echo $ip . "$QQWry->Country$QQWry->Local\n";
/*
结果:
202.201.48.1甘肃省兰州市西北师范大学
*/
本文原创发布php中文网,转载请注明出处,感谢您的尊重!