PHP解析 QQ 纯真 IP 数据库(qqip)

<?php
/**
 * parse ip use http://www.cz88.net database
 */
class QQIp
{

    protected $fp;

    function __construct($file)
    {
        if (! is_file($file)) {
            user_error('file is not found, file=' . $file, E_USER_ERROR);
        }
        $this->fp = fopen($file, 'rb');
        if (! is_resource($this->fp)) {
            user_error('can not open file, file=' . $file, E_USER_ERROR);
        }
    }

    /**
     *
     * @param string $ip
     */
    function parse($ip)
    {
        $fp = $this->fp;
        $ip = explode('.', $ip);
        $ipNum = $ip[0] * 16777216 + $ip[1] * 65536 + $ip[2] * 256 + $ip[3];
        // get start position and end position from db
        $DataBegin = fread($fp, 4);
        $DataEnd = fread($fp, 4);
        $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 = 0;
        $EndNum = $ipAllNum;
        $ip1num = null;
        $ip2num = null;
        // find ip from index use dichotomy
        while ($ip1num > $ipNum || $ip2num < $ipNum) {
            $Middle = intval(($EndNum + $BeginNum) / 2);
            // set the pointer to index position and read 4 byte
            fseek($fp, $ipbegin + 7 * $Middle);
            $ipData1 = fread($fp, 4);
            if (strlen($ipData1) < 4) {
                fclose($fp);
                return '- System Error';
            }
            // convert value to long.Add 2^32 if value is negative
            $ip1num = implode('', unpack('L', $ipData1));
            if ($ip1num < 0)
                $ip1num += pow(2, 32);
            // change end position if value greate than ip address
            if ($ip1num > $ipNum) {
                $EndNum = $Middle;
                continue;
            }
            // get next index
            $DataSeek = fread($fp, 3);
            if (strlen($DataSeek) < 3) {
                fclose($fp);
                return '- System Error';
            }
            $DataSeek = implode('', unpack('L', $DataSeek . chr(0)));
            fseek($fp, $DataSeek);
            $ipData2 = fread($fp, 4);
            if (strlen($ipData2) < 4) {
                fclose($fp);
                return '- System Error';
            }
            $ip2num = implode('', unpack('L', $ipData2));
            if ($ip2num < 0)
                $ip2num += pow(2, 32);
            // not found
            if ($ip2num < $ipNum) {
                if ($Middle == $BeginNum) {
                    fclose($fp);
                    return '- Unknown';
                }
                $BeginNum = $Middle;
            }
        }
        $ipFlag = fread($fp, 1);
        if ($ipFlag == chr(1)) {
            $ipSeek = fread($fp, 3);
            if (strlen($ipSeek) < 3) {
                fclose($fp);
                return '- System Error';
            }
            $ipSeek = implode('', unpack('L', $ipSeek . chr(0)));
            fseek($fp, $ipSeek);
            $ipFlag = fread($fp, 1);
        }
        if ($ipFlag == chr(2)) {
            $AddrSeek = fread($fp, 3);
            if (strlen($AddrSeek) < 3) {
                fclose($fp);
                return '- System Error';
            }
            $ipFlag = fread($fp, 1);
            if ($ipFlag == chr(2)) {
                $AddrSeek2 = fread($fp, 3);
                if (strlen($AddrSeek2) < 3) {
                    fclose($fp);
                    return '- System Error';
                }
                $AddrSeek2 = implode('', unpack('L', $AddrSeek2 . chr(0)));
                fseek($fp, $AddrSeek2);
            } else {
                fseek($fp, - 1, SEEK_CUR);
            }
            while (($char = fread($fp, 1)) != chr(0))
                $ipAddr2 .= $char;
            $AddrSeek = implode('', unpack('L', $AddrSeek . chr(0)));
            fseek($fp, $AddrSeek);
            while (($char = fread($fp, 1)) != chr(0))
                $ipAddr1 .= $char;
        } else {
            fseek($fp, - 1, SEEK_CUR);
            while (($char = fread($fp, 1)) != chr(0))
                $ipAddr1 .= $char;
            $ipFlag = fread($fp, 1);
            if ($ipFlag == chr(2)) {
                $AddrSeek2 = fread($fp, 3);
                if (strlen($AddrSeek2) < 3) {
                    fclose($fp);
                    return '- System Error';
                }
                $AddrSeek2 = implode('', unpack('L', $AddrSeek2 . chr(0)));
                fseek($fp, $AddrSeek2);
            } else {
                fseek($fp, - 1, SEEK_CUR);
            }
            while (($char = fread($fp, 1)) != chr(0))
                $ipAddr2 .= $char;
        }
        fclose($fp);
        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';
        }
        $ipaddr = mb_convert_encoding($ipaddr, 'utf-8', 'GBK');
        return $ipaddr;
    }

    function __destruct()
    {
        fclose($this->fp);
    }
}

下载:QQIp.php

发表评论

电子邮件地址不会被公开。

*