Linux中国论坛's Archiver

lydr 发表于 2006-12-14 23:44

用php实现基于qqwry.dat数据库(就是qq IP数据库)的查询。

[php]<?php

//copyleft xjtux@126.com aniuge007
function getstr(&$fp)
{
while ( 1 ) {
$c = fgetc ( $fp ) ;
if ( ord ( $c[0] ) == 0 )
break ;
$str .= $c ;
}
return $str;
}
function IpToBuf(&$ipadd)
{
$array=explode(".",$ipadd);
$int[0]=chr($array[3]);
$int[1]=chr($array[2]);
$int[2]=chr($array[1]);
$int[3]=chr($array[0]);
$int2=$int[0].$int[1].$int[2].$int[3];
return $int2;
}
function BufToIp(&$int)
{
$array[0]=ord($int[3]);
$array[1]=ord($int[2]);
$array[2]=ord($int[1]);
$array[3]=ord($int[0]);
$int2=implode(".",$array);
return $int2;
}
function BufToOff(&$str)
{
$set=ord($str[0]) + (ord($str[1])*256) + (ord($str[2])*256*256);
return $set;
}
function ipcount(&$buf)
{
$ipcount=ord($buf[0]) + (ord($buf[1])*256) + (ord($buf[2])*256*256) + (ord($buf[3])*256*256*256);
return $ipcount;
}

$ip="59.66.25.1";
$fp=fopen("QQWry.Dat","r");
$startbuf=fread($fp,4);

$startoff=ipcount($startbuf);
$endbuf=fread($fp,4);
$endoff=ipcount($endbuf);
$ipoff=ipcount(IpToBuf($ip));
$RecordCount= (floor( ( $endoff-$startoff) / 7)+1);

//echo $RecordCount." ";

$oip=IpToBuf($ip);
$oip2=ipcount($oip);
$x1=0;
$x2=$RecordCount;

do
{

$x3=floor(($x2+$x1)/2);
$oboff=$startoff+$x3*7;
fseek($fp,$oboff,SEEK_SET);
$ipbuf=fread($fp,4);

$buf=fread($fp,3);
$ipbuf2=fread($fp,4);
$ipoff=ipcount($ipbuf);
$ipoff2=ipcount($ipbuf2);
if(($ipoff<$oip2) && ($ipoff2>$oip2))break;
if($ipoff>$oip2)$x2=$x3;
elseif($ipoff<$oip2)$x1=$x3;
else break;
}
while(1);

/*for($x1=0;$x1<$RecordCount;$x1++)
{
fseek($fp,$startoff,SEEK_SET);
$ipbuf=fread($fp,4);
$ipoff=ipcount($ipbuf);

if( $ipoff>$oip2)
{
$startoff-=7;
break;
}
if(($ipoff==$oip2))break;
$startoff+=7;

}
*/
$off=BufToOff($buf);
fseek($fp,$off,SEEK_SET);
$ipbuf=fread($fp,4);
$flag=ord(fread($fp,1));
switch($flag)
{
case 2:
//echo " 2 ";
$buf=fread($fp,3);
$local=getstr($fp);
$off=BufToOff($buf);
fseek($fp,$off,SEEK_SET);
$country=getstr($fp);
break;
case 0:
$country="未知地址";
$local="";
break;
case 1:
$buf=fread($fp,3);
$off=BufToOff($buf);
fseek($fp,$off,SEEK_SET);
$flag=ord(fread($fp,1));
if($flag!==2)
{
fseek($fp,$off,SEEK_SET);
$country=getstr($fp);

$local=getstr($fp);

}
else{

$buf=fread($fp,3);
$countryoff=BufToOff($buf);

$flag=ord(fread($fp,1));
if($flag==1 || $flag==2)
{
$buf=fread($fp,3);
$off=BufToOff($buf);
fseek($fp,$off,SEEK_SET);
$local=getstr($fp);
}else{

@fseek($fp,$off+4,SEEK_SET);
//fseek($fp,(ftell($fp)-1),SEEK_SET);
$local=getstr($fp);
}
fseek($fp,$countryoff,SEEK_SET);
$country=getstr($fp);
}break;
default:

@fseek($fp,$off+4,SEEK_SET);
$country=getstr($fp);
$local=getstr($fp);
}


$ip2=BufToIp($ipbuf);

echo " ".$ip2." ";
echo $country." ";
echo $local." ";

fclose($fp);

?> [/php]
ip数据库的说明详见:
[url=http://www.xymo.net/blog/showlog.asp...=953&cat_id=28]http://www.xymo.net/blog/showlog.asp...=953&cat_id=28[/url]

这是我第一次写php,有什么错误欢迎批评指正,3x

页: [1]

Powered by Discuz! Archiver 6.1.0  © 2001-2007 Comsenz Inc.