纯真IP库最新版哪里下载?如何使用PHP解析纯真ip?
发布于 作者:苏南大叔 来源:程序如此灵动~ 我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...
伴随着中国互联网的发展史,从当年的显IPQQ开始,大名鼎鼎的纯真数据库qqwry,就伴随着中国人的网络史而存在。当年的木子QQ
,珊瑚虫QQ
,后来的DZ论坛等等,都有qqwry的存在,这个数据库的名称是怎么来的,无从得知。qqwry.dat
是谁维护的也不知晓。不过可以肯定的是:qqwry.dat
应该是当年做站必备利器。
废话背景分析
最近,苏南大叔想做个ip相关的判断,所以就又想起了它。百度了一番,发现它居然有个官方站,
界面呢,以最新的网络观来说,略low。似乎有些苍白的感觉。不管如何,界面上面有个明显的下载按钮。点击之后,令我意外的是,居然是个exe。说好的dat文件呢?好吧,可能在exe里面包含着呢。不情愿的安装了exe后,果然在目录下面发现了期待的qqwry.dat。看着exe的界面上有个“升级”的按钮的份上,就保留了exe。嘿嘿,没准哪天还真心升级下呢。
然后百度个PHP
解析的代码吧,发现了个大名鼎鼎的dz的,试了一下。貌似有问题,似乎其中的正则部分,有问题。而苏南大叔最不喜欢正则了,所以直接过了。然后又百度到了大名鼎鼎的thinkphp
的作者liu21st
的作品。马上膜拜一下下。下载回来试试,果然赞。
php
解析代码
下面贴出苏南大叔修改过的@liu21st的ip
代码解析,稍稍修改了下逻辑,能清楚的标识出国家是中国的情况,并且添加上了丢失的函数。大家喜欢就拿走好了。
class IpLocation {
private $fp;
private $firstip;
private $lastip;
private $totalip;
public function __construct($filename = "data/qqwry.dat") {
$this->fp = 0;
if (($this->fp = fopen(dirname(__FILE__) . '/' . $filename, 'rb')) !== false) {
$this->firstip = $this->getlong();
$this->lastip = $this->getlong();
$this->totalip = ($this->lastip - $this->firstip) / 7;
}
}
private function getlong() {
//将读取的little-endian编码的4个字节转化为长整型数
$result = unpack('Vlong', fread($this->fp, 4));
return $result['long'];
}
private function getlong3() {
$result = unpack('Vlong', fread($this->fp, 3) . chr(0));
return $result['long'];
}
private function packip($ip) {
return pack('N', intval(ip2long($ip)));
}
private function getstring($data = "") {
$char = fread($this->fp, 1);
while (ord($char) > 0) {
$data .= $char;
$char = fread($this->fp, 1);
}
return $data;
}
private function getarea() {
$byte = fread($this->fp, 1);
switch (ord($byte)) {
case 0:
$area = "";
break;
case 1:
case 2:
fseek($this->fp, $this->getlong3());
$area = $this->getstring();
break;
default:
$area = $this->getstring($byte);
break;
}
return $area;
}
private $provinces = array("黑龙江省", "辽宁省", "吉林省", "河北省", "河南省", "湖北省", "湖南省", "山东省", "山西省", "陕西省","安徽省", "浙江省", "江苏省", "福建省", "广东省", "海南省", "四川省", "云南省", "贵州省", "青海省", "甘肃省","江西省", "台湾省", "内蒙古", "宁夏", "新疆", "西藏", "广西", "北京市", "上海市", "天津市", "重庆市", "香港", "澳门");
public function getlocation($ip = '') {
if (!$this->fp)
return null;
if (empty($ip))
$ip = get_client_ip();
$location['ip'] = gethostbyname($ip);
$ip = $this->packip($location['ip']);
$l = 0;
$u = $this->totalip;
$findip = $this->lastip;
while ($l <= $u) {
$i = floor(($l + $u) / 2);
fseek($this->fp, $this->firstip + $i * 7);
$beginip = strrev(fread($this->fp, 4));
if ($ip < $beginip) {
$u = $i - 1;
} else {
fseek($this->fp, $this->getlong3());
$endip = strrev(fread($this->fp, 4));
if ($ip > $endip) {
$l = $i + 1;
} else {
$findip = $this->firstip + $i * 7;
break;
}
}
}
fseek($this->fp, $findip);
$location['beginip'] = long2ip($this->getlong());
$offset = $this->getlong3();
fseek($this->fp, $offset);
$location['endip'] = long2ip($this->getlong());
$byte = fread($this->fp, 1);
switch (ord($byte)) {
case 1:
$countryOffset = $this->getlong3();
fseek($this->fp, $countryOffset);
$byte = fread($this->fp, 1);
switch (ord($byte)) {
case 2:
fseek($this->fp, $this->getlong3());
$location['country'] = $this->getstring();
fseek($this->fp, $countryOffset + 4);
$location['area'] = $this->getarea();
break;
default:
$location['country'] = $this->getstring($byte);
$location['area'] = $this->getarea();
break;
}
break;
case 2:
fseek($this->fp, $this->getlong3());
$location['country'] = $this->getstring();
fseek($this->fp, $offset + 8);
$location['area'] = $this->getarea();
break;
default:
$location['country'] = $this->getstring($byte);
$location['area'] = $this->getarea();
break;
}
if (trim($location['country']) == 'CZ88.NET') {
$location['country'] = '未知';
}
if (trim($location['area']) == 'CZ88.NET') {
$location['area'] = '';
}
$location['country'] = @iconv('gbk', 'utf-8', $location['country']);
$location['area'] = @iconv('gbk', 'utf-8', $location['area']);
foreach ($this->provinces as $v) {
if (strpos($location['country'], $v) === 0) {
$location['province'] = $v;
$location['city'] = str_replace($v, '', $location['country']);
break;
}
}
if (empty($location['province']))
$location['province'] = $location['country'];
if (empty($location['city']))
$location['city'] = $location['country'];
//sunan moify
if (in_array($location['province'], $this->provinces)) {
$location['country'] = "中国";
}
return $location;
}
public function __destruct() {
if ($this->fp) {
fclose($this->fp);
}
$this->fp = 0;
}
}
function get_client_ip() {
if (getenv('HTTP_CLIENT_IP')) {
$onlineip = getenv('HTTP_CLIENT_IP');
} elseif (getenv('HTTP_X_FORWARDED_FOR')) {
$onlineip = getenv('HTTP_X_FORWARDED_FOR');
} elseif (getenv('REMOTE_ADDR')) {
$onlineip = getenv('REMOTE_ADDR');
} else {
$onlineip = $HTTP_SERVER_VARS['REMOTE_ADDR'];
}
return $onlineip;
}
header("Content-type: text/html; charset=utf-8");
$new = new IpLocation();
$ip = $new->getlocation();
//$ip = $new->getlocation("114.249.231.28");
print_r($ip);
结束语
更多php
文章,请点击下面的链接:
如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。