PHP读取纯真IP数据库QQWry.dat

标签: , ,

纯真 IP 数据库 QQWry.dat 出来都那么多年了,网上用 PHP 读取 QQWry.dat 的代码满天飞,我就没有必要重复造轮子了。以下代码摘自 Discuz! X2 的 function_misc.php。

<?php
function convertip_full($ip, $ipdatafile) {

    if(!$fd = @fopen($ipdatafile, 'rb')) {
        return '- Invalid IP data file';
    }

    $ip = explode('.', $ip);
    $ipNum = $ip[0] * 16777216 + $ip[1] * 65536 + $ip[2] * 256 + $ip[3];

    if(!($DataBegin = fread($fd, 4)) || !($DataEnd = fread($fd, 4)) ) return;
    @$ipbegin = implode('', unpack('L', $DataBegin));
    if($ipbegin < 0) $ipbegin += pow(2, 32);
    @$ipend = implode('', unpack('L', $DataEnd));
    if($ipend < 0) $ipend += pow(2, 32);
    $ipAllNum = ($ipend - $ipbegin) / 7 + 1;

    $BeginNum = $ip2num = $ip1num = 0;
    $ipAddr1 = $ipAddr2 = '';
    $EndNum = $ipAllNum;

    while($ip1num > $ipNum || $ip2num < $ipNum) {
        $Middle= intval(($EndNum + $BeginNum) / 2);

        fseek($fd, $ipbegin + 7 * $Middle);
        $ipData1 = fread($fd, 4);
        if(strlen($ipData1) < 4) {
            fclose($fd);
            return '- System Error';
        }
        $ip1num = implode('', unpack('L', $ipData1));
        if($ip1num < 0) $ip1num += pow(2, 32);

        if($ip1num > $ipNum) {
            $EndNum = $Middle;
            continue;
        }

        $DataSeek = fread($fd, 3);
        if(strlen($DataSeek) < 3) {
            fclose($fd);
            return '- System Error';
        }
        $DataSeek = implode('', unpack('L', $DataSeek.chr(0)));
        fseek($fd, $DataSeek);
        $ipData2 = fread($fd, 4);
        if(strlen($ipData2) < 4) {
            fclose($fd);
            return '- System Error';
        }
        $ip2num = implode('', unpack('L', $ipData2));
        if($ip2num < 0) $ip2num += pow(2, 32);

        if($ip2num < $ipNum) {
            if($Middle == $BeginNum) {
                fclose($fd);
                return '- Unknown';
            }
            $BeginNum = $Middle;
        }
    }

    $ipFlag = fread($fd, 1);
    if($ipFlag == chr(1)) {
        $ipSeek = fread($fd, 3);
        if(strlen($ipSeek) < 3) {
            fclose($fd);
            return '- System Error';
        }
        $ipSeek = implode('', unpack('L', $ipSeek.chr(0)));
        fseek($fd, $ipSeek);
        $ipFlag = fread($fd, 1);
    }

    if($ipFlag == chr(2)) {
        $AddrSeek = fread($fd, 3);
        if(strlen($AddrSeek) < 3) {
            fclose($fd);
            return '- System Error';
        }
        $ipFlag = fread($fd, 1);
        if($ipFlag == chr(2)) {
            $AddrSeek2 = fread($fd, 3);
            if(strlen($AddrSeek2) < 3) {
                fclose($fd);
                return '- System Error';
            }
            $AddrSeek2 = implode('', unpack('L', $AddrSeek2.chr(0)));
            fseek($fd, $AddrSeek2);
        } else {
            fseek($fd, -1, SEEK_CUR);
        }

        while(($char = fread($fd, 1)) != chr(0))
        $ipAddr2 .= $char;

        $AddrSeek = implode('', unpack('L', $AddrSeek.chr(0)));
        fseek($fd, $AddrSeek);

        while(($char = fread($fd, 1)) != chr(0))
        $ipAddr1 .= $char;
    } else {
        fseek($fd, -1, SEEK_CUR);
        while(($char = fread($fd, 1)) != chr(0))
        $ipAddr1 .= $char;

        $ipFlag = fread($fd, 1);
        if($ipFlag == chr(2)) {
            $AddrSeek2 = fread($fd, 3);
            if(strlen($AddrSeek2) < 3) {
                fclose($fd);
                return '- System Error';
            }
            $AddrSeek2 = implode('', unpack('L', $AddrSeek2.chr(0)));
            fseek($fd, $AddrSeek2);
        } else {
            fseek($fd, -1, SEEK_CUR);
        }
        while(($char = fread($fd, 1)) != chr(0))
        $ipAddr2 .= $char;
    }
    fclose($fd);

    if(preg_match('/http/i', $ipAddr2)) {
        $ipAddr2 = '';
    }
    $ipaddr = "$ipAddr1 $ipAddr2";
    $ipaddr = preg_replace('/CZ88\.NET/is', '', $ipaddr);
    $ipaddr = preg_replace('/^\s*/is', '', $ipaddr);
    $ipaddr = preg_replace('/\s*$/is', '', $ipaddr);
    if(preg_match('/http/i', $ipaddr) || $ipaddr == '') {
        $ipaddr = '- Unknown';
    }

    return '- '.$ipaddr;

}
?>

虽然有些地方写得有点诡异,但是能用就行。

赞赏

微信赞赏支付宝赞赏

随机文章:

  1. JavaScript中的闭包(closures)
  2. WScript.Shell对象SpecialFolders属性未公开文档
  3. EditPlus 3.30
  4. Unicode中的CIRCLED NUMBER
  5. VBS Scripting.Dictionary字典对象按键名Key进行冒泡排序

4 条评论 发表在“PHP读取纯真IP数据库QQWry.dat”上

  1. 艳文说道:

    这个不错 嘿嘿 拿走了 顺便说一下 在你博客想留个言太麻烦了 还要自己在源代码里面添加个submit的按钮在可以提交。。。。。呵呵

  2. Zjmainstay说道:

    很好!!搜藏了!!话说QQwry IP库可以上这里取:http://www.newxing.com/Code/tool/QQwry.dat_608.html

    • Zjmainstay说道:

      刚刚发现读取出来的字符是gb2312编码的,所以使用UTF-8的项目建议做轻微改动。GB2312的直接忽视~~
      function convertip_full($ip, $ipdatafile,$charset=’UTF-8′) {
      //其他不变
      return iconv(‘GB2312′,$charset,’- ‘.$ipaddr);
      }

  3. Jimmy说道:

    $ipaddr = iconv(‘gbk’, ‘utf-8//IGNORE’, $ipaddr); //转换编码,如果网页的gbk可以删除此行

Jimmy 留下回复