仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 1181|回复: 18
打印 上一主题 下一主题

[学习教程] PHP教程之QQwry.dat格局剖析和查询IP地位的PHP程...

[复制链接]
小魔女 该用户已被删除
跳转到指定楼层
#
发表于 2015-2-4 00:22:51 | 只看该作者 回帖奖励 |正序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

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基础。
蒙在股里 该用户已被删除
18#
发表于 2015-5-6 03:11:47 | 只看该作者
你很难利用原理去编写自己的代码。对于php来说,系统的学习我认为还是很重要的,当你有一定理解后,你可你针对某种效果研究,我想那时你不会只是复制代码的水平了。
海妖 该用户已被删除
17#
发表于 2015-4-30 15:37:28 | 只看该作者
环境搭建好,当你看见你的浏览器输出“it works\\\\\\\"时你一定是喜悦的。在你解决问题的时候,我强烈建议多读php手册。
飘飘悠悠 该用户已被删除
16#
发表于 2015-4-27 02:35:21 | 只看该作者
微软最近出的新字体“微软雅黑”,虽然是挺漂亮的,不过firefox  支持的不是很好,所以能少用还是少用的好。
灵魂腐蚀 该用户已被删除
15#
发表于 2015-4-26 03:09:02 | 只看该作者
作为一个合格的coder 编码的规范是必须,命名方面我推崇“驼峰法”,另外就是自己写的代码最好要带注释,不然时间长了,就算是自己的代码估计看起来都费事,更不用说别人拉。
金色的骷髅 该用户已被删除
14#
发表于 2015-4-17 07:18:12 | 只看该作者
刚开始安装php的时候,我图了个省事,把php的扩展全都打开啦(就是把php.ini 那一片 extension 前面的冒号全去掉啦),这样自然有好处,以后不用再需要什么功能再来打开。
第二个灵魂 该用户已被删除
13#
发表于 2015-3-27 18:09:50 | 只看该作者
首推的搜索引擎当然是Google大神,其次我比较喜欢 百度知道。不过搜出来的结果往往都是 大家copy来copy去的,运气的的概率很大。
乐观 该用户已被删除
12#
发表于 2015-3-27 18:07:30 | 只看该作者
Apache不是非得用80或者8080端口的,我刚开始安得时候就是80端口老占用,就用了个 81端口,结果照常,就是输localhost的时候,应该输入为 localhost:81
兰色精灵 该用户已被删除
11#
发表于 2015-3-23 05:46:52 | 只看该作者
首先声明:我是一个菜鸟,是一个初学者。学习了一段php后总是感觉自己没有提高,无奈。经过反思我认为我学习过程中存在很多问题,我改变了学习方法后自我感觉有了明显的进步。
谁可相欹 该用户已被删除
10#
发表于 2015-3-19 03:33:43 | 只看该作者
装在C盘下面可以利用windows的ghost功能可以还原回来(顺便当做是重转啦),当然啦我的编译目录要放在别的盘下,不然自己的劳动成果就悲剧啦。
若相依 该用户已被删除
9#
发表于 2015-3-13 01:08:21 | 只看该作者
要进行开发,搭建环境是首先需要做的事,windows下面我习惯把环境那个安装在C盘下面,因为我配的环境经常出现诡异事件,什么事都没做环境有的时候就不能用啦。
活着的死人 该用户已被删除
8#
发表于 2015-3-11 17:09:11 | 只看该作者
我还是强烈建议自己搭建php环境。因为在搭建的过程中你会遇到一些问题,通过搜索或是看php手册解决问题后,你会更加深刻的理解它们的工作原理,了解到php配置文件中的一些选项设置。
简单生活 该用户已被删除
7#
发表于 2015-3-4 14:21:29 | 只看该作者
找到的的资料很多都是在论坛里的,需要注册,所以我一般没到一个论坛都注册一个id,所有的id都注册成一样的,这样下次再进来的时候就不用重复注册啦。当然有些论坛的某些资料是需要的付费的。
变相怪杰 该用户已被删除
6#
发表于 2015-3-1 23:51:41 | 只看该作者
做为1门年轻的语言,php一直很努力。
因胸联盟 该用户已被删除
5#
发表于 2015-2-11 08:03:52 | 只看该作者
Apache不是非得用80或者8080端口的,我刚开始安得时候就是80端口老占用,就用了个 81端口,结果照常,就是输localhost的时候,应该输入为 localhost:81
柔情似水 该用户已被删除
地板
发表于 2015-2-10 16:09:22 | 只看该作者
找到的的资料很多都是在论坛里的,需要注册,所以我一般没到一个论坛都注册一个id,所有的id都注册成一样的,这样下次再进来的时候就不用重复注册啦。当然有些论坛的某些资料是需要的付费的。
再现理想 该用户已被删除
板凳
发表于 2015-2-9 16:46:52 | 只看该作者
我还是推荐用firefox ,配上firebug 插件调试js能省下不受时间。谷歌的浏览器最好也不少用,因为谷歌的大侠们实在是太天才啦,把一些原来的js代码加了一些特效。
飘灵儿 该用户已被删除
沙发
发表于 2015-2-6 16:49:01 | 只看该作者
php里的数组为空的时候是不能拿来遍历的;(这个有点低级啊,不过我刚被这个边界问题墨迹了好长一会)
小魔女 该用户已被删除
楼主
 楼主| 发表于 2015-2-4 23:55:44 | 只看该作者
我要在声明一下:我是个菜鸟!!我对php这门优秀的语言也是知之甚少。但是我要在这里说一下php在网站开发中最常用的几个功能:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-12-24 20:21

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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