LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1532|回复: 2

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

[复制链接]
发表于 2005-5-22 01:00:48 | 显示全部楼层 |阅读模式
<?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);

?>

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

这是我第一次写php,有什么错误欢迎批评指正,3x   :cool:
发表于 2005-5-22 12:48:08 | 显示全部楼层
不错
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-5-22 17:57:03 | 显示全部楼层
又多了篇精华贴,8容易啊。。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表