<iframe align="center" marginwidth="0" marginheight="0" src="http://www.zealware.com/csdnblog336280.html" frameborder="0" width="336" scrolling="no" height="280"></iframe>
Discuz 5.0 中读取纯真IP数据库函数分析
Discuz 5.0不在使用自己的IP数据,而是使用纯真IP的数据格式,存取纯真IP数据库稍微有点麻烦,它的存储格式比较特殊也很有趣,具体的格式分析参考下面两个链接,其他语言实现参考文章末的链接。
《纯真IP数据库格式详解》
链接一:http://blog.csdn.net/heiyeshuwu/archive/2006/05/12/725675.aspx
链接二:http://lumaqq.linuxsir.org/article/qqwry_format_detail.html
纯真IP数据库官网:http://www.cz88.net/ip/
纯真IP数据库下载:http://update.cz88.net/soft/qqwry.rar
以下函数conrvertip()位于 Discuz!5_GBK/upload/include/misc.func.php 路径中,有兴趣可以具体去阅读分析。(下面代码我做了简单的修改,更便于阅读,核心没有修改)
//===================================
//
//功能:IP地址获取真实地址函数
//参数:$ip-IP地址
//作者:[Discuz!](C)ComsenzInc.
//
//===================================
functionconvertip($ip){
//IP数据文件路径
$dat_path='QQWry.Dat';
//检查IP地址
if(!preg_match("/^d{1,3}.d{1,3}.d{1,3}.d{1,3}$/",$ip)){
return'IPAddressError';
}
//打开IP数据文件
if(!$fd=@fopen($dat_path,'rb')){
return'IPdatefilenotexistsoraccessdenied';
}
//分解IP进行运算,得出整形数
$ip=explode('.',$ip);
$ipNum=$ip[0]*16777216+$ip[1]*65536+$ip[2]*256+$ip[3];
//获取IP数据索引开始和结束位置
$DataBegin=fread($fd,4);
$DataEnd=fread($fd,4);
$ipbegin=implode('',unpack('L',$DataBegin));
if($ipbegin0)$ipbegin+=pow(2,32);
$ipend=implode('',unpack('L',$DataEnd));
if($ipend0)$ipend+=pow(2,32);
$ipAllNum=($ipend-$ipbegin)/7+1;
$BeginNum=0;
$EndNum=$ipAllNum;
//使用二分查找法从索引记录中搜索匹配的IP记录
while($ip1num>$ipNum||$ip2num$ipNum){
$Middle=intval(($EndNum+$BeginNum)/2);
//偏移指针到索引位置读取4个字节
fseek($fd,$ipbegin+7*$Middle);
$ipData1=fread($fd,4);
if(strlen($ipData1)4){
fclose($fd);
return'SystemError';
}
//提取出来的数据转换成长整形,如果数据是负数则加上2的32次幂
$ip1num=implode('',unpack('L',$ipData1));
if($ip1num0)$ip1num+=pow(2,32);
//提取的长整型数大于我们IP地址则修改结束位置进行下一次循环
if($ip1num>$ipNum){
$EndNum=$Middle;
continue;
}
//取完上一个索引后取下一个索引
$DataSeek=fread($fd,3);
if(strlen($DataSeek)3){
fclose($fd);
return'SystemError';
}
$DataSeek=implode('',unpack('L',$DataSeek.chr(0)));
fseek($fd,$DataSeek);
$ipData2=fread($fd,4);
if(strlen($ipData2)4){
fclose($fd);
return'SystemError';
}
$ip2num=implode('',unpack('L',$ipData2));
if($ip2num0)$ip2num+=pow(2,32);
//没找到提示未知
if($ip2num$ipNum){
if($Middle==$BeginNum){
fclose($fd);
return'Unknown';
}
$BeginNum=$Middle;
}
}
//下面的代码读晕了,没读明白,有兴趣的慢慢读
$ipFlag=fread($fd,1);
if($ipFlag==chr(1)){
$ipSeek=fread($fd,3);
if(strlen($ipSeek)3){
fclose($fd);
return'SystemError';
}
$ipSeek=implode('',unpack('L',$ipSeek.chr(0)));
fseek($fd,$ipSeek);
$ipFlag=fread($fd,1);
}
if($ipFlag==chr(2)){
$AddrSeek=fread($fd,3);
if(strlen($AddrSeek)3){
fclose($fd);
return'SystemError';
}
$ipFlag=fread($fd,1);
if($ipFlag==chr(2)){
$AddrSeek2=fread($fd,3);
if(strlen($AddrSeek2)3){
fclose($fd);
return'SystemError';
}
$AddrSeek2=implode('',unpack('L',$AddrSeek2.chr(0)));
fseek($fd,$AddrSeek2);
}else{
fseek($fd,-1,SEEK_CUR);
}
while(($char=fread($fd,1))!=chr(0))
$ipAddr2.=$char;
$AddrSeek=implode('',unpack('L',$AddrSeek.chr(0)));
fseek($fd,$AddrSeek);
while(($char=fread($fd,1))!=chr(0))
$ipAddr1.=$char;
}else{
fseek($fd,-1,SEEK_CUR);
while(($char=fread($fd,1))!=chr(0))
$ipAddr1.=$char;
$ipFlag=fread($fd,1);
if($ipFlag==chr(2)){
$AddrSeek2=fread($fd,3);
if(strlen($AddrSeek2)3){
fclose($fd);
return'SystemError';
}
$AddrSeek2=implode('',unpack('L',$AddrSeek2.chr(0)));
fseek($fd,$AddrSeek2);
}else{
fseek($fd,-1,SEEK_CUR);
}
while(($char=fread($fd,1))!=chr(0)){
$ipAddr2.=$char;
}
}
fclose($fd);
//最后做相应的替换操作后返回结果
if(preg_match('/http/i',$ipAddr2)){
$ipAddr2='';
}
$ipaddr="$ipAddr1$ipAddr2";
$ipaddr=preg_replace('/CZ88.NET/is','',$ipaddr);
$ipaddr=preg_replace('/^s*/is','',$ipaddr);
$ipaddr=preg_replace('/s*$/is','',$ipaddr);
if(preg_match('/http/i',$ipaddr)||$ipaddr==''){
$ipaddr='Unknown';
}
return$ipaddr;
}
//========================
//
//调用举例(速度很快)
//
//========================
echoconvertip('219.238.235.10');
//输出:北京市电信通
echoconvertip('23.56.82.12');
//输出:IANA
echoconvertip('250.69.52.0');
//输出:IANA保留地址
echoconvertip('238.69.52.0');
//输出:IANA保留地址用于多点传送
echoconvertip('192.168.0.1');
//输出:局域网对方和您在同一内部网
echoconvertip('255.255.255.255');
//输出:纯真网络2006年11月20日IP数据
?>
附:(相应其他实现程序)
利用 QQWry.Dat 实现 IP 地址高效检索(PHP)(作者: andot)
纯真IP数据库(QQWry.Dat)查询 C源码(作者:Windix)
相关推荐
Discuz 5.0 中读取纯真IP数据库函数分析
discuz wry纯真ip库 discuz wry纯真ip库 discuz wry纯真ip库discuz wry纯真ip库
纯真Ip地址库,可用于提取Ip地址对应的城市
很简单的,最基础的,完全是很牛逼的 很简单的,最基础的,完全是很牛逼的 很简单的,最基础的,完全是很牛逼的
数据来源于 纯真网络2005年6月10日IP数据 上传IPDATA文件夹中即可
Discuz4.1_5.0会员整合插件
5.0 patch 20061001 ============================ <br/>升级方法: 将 upload 目录中的文件上传到服务器,直接覆盖以前的文件即可。 <br/>注意事项: 本修补文件仅仅适用于 Discuz! 5.0 正式...
5.0 patch 20060911 ============================ <br/>升级方法: 将 upload 目录中的文件上传到服务器,直接覆盖以前的文件即可。 <br/>注意事项: 本修补文件仅仅适用于 Discuz! 5.0 正式...
discuz开发必备常用函数 ,Discuz!常用函数解析 php, 函数, Discuz, param, Discuz二次开发 /* [Discuz!] (C)2001-2007 Comsenz Inc. This is NOT a freeware, use is subject to license terms $Id: global.func...
5.0 Lite 4ngel精简版 Build20070215_discuz!_5.0.0_lite[论坛社区]Discuz! 5.0 Lite 4ngel精简版 Build20070215_discuz!_5.0.0_lite 1.适合个人搭建网站项目参考 2.适合学生毕业设计搭建网站参考 3.适合小公司搭建...
讨论获取客户端IP 地址前,我们首先下弄明白的是以下三个的具体含义:REMOTE_ADDR,HTTP_CLIENT_IP,HTTP_X_FORWARDED_FOR REMOTE_ADDR 是你的客户端跟你的服务器“握手”时候的IP。如果使用了“匿名代理”,REMOTE...
详解Discuz!X1.5 showmessage函数详解Discuz!X1.5 showmessage函数
php仿discuz分页样式,分页函数。
这个是安装说明文件,里面要用的安装文件,除了MYSQL 5。0太大,不能上传,其他的都上传了!!安装文件免费共享了,想快速安装成功的兄弟,请下载这个说明文件,我要收3分哦!我也想去下别人的好东西!...
2.运行下列SQL语句:(如6.1版论坛时已曾安装过开口中插件,升级数据语可忽略,只须从新覆盖文件与源码修改)DROP TABLE IF EXISTS cdb_mouth; CREATE TABLE cdb_mouth ( id int(4) NOT NULL auto_increment, ...
Discuz!常用全局变量及函数.chm。。。。。。。。。。。。。。。
超级出名的bbs源码discuz! 5.0的数据库结构信息说明文档,网上寻找很久才挖到得,建议下载学习。
互动百科hdwiki5.0(utf-8)最新版,是国内唯一的百科系统源码,可以discuz phpwind uc 等系统结合,功能强大,安装是只要把解压的upload文件夹放在php运行环境根目录下,浏览器运行http://localhost/upload即可
信阳热线5.0是基于最新版dede5.7sp1内核开发构建的,网站带全部数据。并整合了discuz论坛,实现一站注册登陆。 网站包括文章、图片、下载、商城、二手、人才、交友、游戏、电影、音乐、留言、黄页、圈子、问答、论坛...