• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • QQwry.dat格式分析和查詢IP位置的PHP程序

    發表于:2007-07-14來源:作者:點擊數: 標簽:
    QQwry.dat格式分析和查詢IP位置的 PHP 程序 By Strongc http://strongc.51.net/d2x/ 轉載時不要去掉我的名字和我的主頁鏈接,謝謝! 以前的追捕 數據庫 太大,而且很久沒有更新了。 所以我想到利用QQwry.dat這個文件查詢IP所在位置,QQwry.dat 在很多地方都
    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("(我們一定要解放臺灣?。。。?quot;, "", $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 ;
    }

    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>