|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
建议大家买一本书,而不光是在网上看一些零碎的资料,一本书毕竟会讲的系统一些,全面一些,而且印刷的书不受电脑的限制,但是建议在看书的时候最好旁边有电脑,这样可以很及时地上机实践。法式 QQwry.dat格局剖析和查询IP地位的PHP法式
By Strongc http://strongc.51.net/d2x/
转载时不要去失落我的名字和我的主页链接,感谢!
之前的追捕数据库太大,并且好久没有更新了。
所以我想到使用QQwry.dat这个文件查询IP地点地位,QQwry.dat 在良多中央都能找到,普通看IP地址的QQ紧缩包中都有。
然而没有任何相干格局材料。
我剖析了这个文件的格局,今朝以下结论:
格局以下:
A。文件头,共8字节
B。若干笔记录的停止地址+国度和区域
C。依照从小到大分列的若干条肇端地址+停止地址偏移,定长,7字节
D。一切的IP都是用4字节整数纪录的,而且遵守Intel次第,高位在后,低位在前。
E。一切偏移量都是相对偏移,就是从文件最开首盘算。
F。除文件头用了两个4字节偏移,其他偏移量都用3字节。
G。一切的偏移量也是低位在前,高位在后
H。采取了一些字符串紧缩手艺
1。文件头,共8字节
FirstStartIpOffset:4 第一个肇端IP的相对偏移
LastStartIpOffset:4 最初一个肇端IP的相对偏移
2。肇端地址+停止地址偏移纪录区
每笔记录7字节,依照肇端地址从小到大分列
StartIp:4 肇端地址,整数模式的IP
EndIpOffset:3 停止地址相对偏移
3。停止地址+国度+区域纪录区
EndIP:4
国度+区域纪录:不定长
4。国度+区域纪录,有几种模式
4.1。
国度字符串,以 0x0 停止
区域字符串,以 0x0 停止
4.2。
Flag:1 标识取值: 0x1,前面没有Local纪录
0x2,前面还有Local纪录
sCountryOffset:3 实践的字符串要去这个偏移地位去找
LocalRec:不定长,可选 依据Flag取值而定。这个纪录也相似Country,能够采取紧缩
4.3 LocalRec布局一
flag:1 还不是非常懂得这个flag寄义,取值 0x1 or 0x2
sLocalOffset:3
4.4 LocalRec布局二
sLocal:不定长 通俗的C作风字符串
注重:sCountryOffset指向的地位能够仍然是4.2格局的,不晓得为何如许设计。
Flag取0x1时,sCountryOffset指向的地位多是Flag为0x2,这时候,LocalRec也在这里寻觅。
如今不分明当纪录Local的地位碰到0x2的标记意味着甚么。
在qqwry.dat中,仿佛存在一些毛病。
一般的纪录Local会被写为:
0x2,0x0,0x0,0x0
依据划定规矩,应当到文件最开首去寻觅,可是,文件最开首明显不是纪录这些的。
我才学PHP不久,列位不要笑,你要能改善固然好,记得给我一份。
我参考了一些网上找到的代码,就纷歧一写出出处了。
说厚道话,我很头疼PHP没法明白指定变量的类型。
好比,我想让某个数是无符号的整形,它很不听话,非如果带个负号,我只好测验考试各类能够的写法..........
列位都是怎样处置相似的工作?
define('QQWRY' , $qqwry_root_path . 'QQwry.dat' ) ;
function IpToInt($Ip) {
$array=explode('.',$Ip);
$Int=($array[0] * 256*256*256) + ($array[1]*256*256) + ($array[2]*256) + $array[3];
return $Int;
}
function IntToIp($Int) {
$b1=($Int & 0xff000000)>>24;
if ($b1<0) $b1+=0x100;
$b2=($Int & 0x00ff0000)>>16;
if ($b2<0) $b2+=0x100;
$b3=($Int & 0x0000ff00)>>8;
if ($b3<0) $b3+=0x100;
$b4= $Int & 0x000000ff;
if ($b4<0) $b4+=0x100;
$Ip=$b1.'.'.$b2.'.'.$b3.'.'.$b4;
return $Ip;
}
class TQQwry
{
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) ;
//echo sprintf('EndIpOffset=(%x)',$this->EndIpOff );
$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) {
$nRet;
$ip = 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 <= 1){
$this->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 <= $ip ) && ( $this->EndIp >= $ip ) ){
$nRet = 0 ;
$this->getCountry ( ) ;
//如许不太好..............所以..........
$this->Local = str_replace("(咱们必定要束缚台湾!!!)", "", $this->Local);
}else {
$nRet = 3 ;
$this->Country = '未知' ;
$this->Local = '' ;
}
fclose ( $this->fp ) ;
return $nRet ;
}
}
function ip2location ( $ip )
{
$wry = new TQQwry ;
$nRet = $wry->qqwry ( $ip );
//可以使用 $nRet做一些工作,我是让他主动纪录未知IP到一个表,代码就不写了。
return $wry->Country.$wry->Local ;
}
培训的第一阶段,学习的是HTML/CSS/JavaScript基础。 |
|