想用纯真数据库做个ip查询系统(数据已经得到),用什么工具,怎么建立自己纯真数据库,才符合规范?用iplook把qqwry.dat 修改成自己的数据库,可以实现么? 这种方法是否有点麻烦啊。【PS:222.25.145.148.0/24-222.25.145.153.0/24 这个ip段是怎么回事呢? 怎么有5个字节?】

解决方案 »

  1.   

    这是前辈的代码class MIC_query
    {
    var $fd;
    var $inum;
    var $off1;
    var $off2;
    var $flag;
    var $chrono; function MIC_query($fpath = '')
    {
    $this->fd = false;
    $this->off1 = $this->off2 = 0;
    if ($fpath != '') $this->open($fpath);
    } function & open($fpath = '')
    {
    if (!isset($this))
    {
    $name = defined('__CLASS__') ? __CLASS__ : 'MIC_query';
    $obj = new $name;
    if ($obj->open($fpath)) return $obj;
    return false;
    }
    if ($fpath == '') $fpath = dirname(__FILE__) . '/mic.dat';
    if (!($fd = fopen($fpath, 'rb')))
    {
    trigger_error("Cann't open the MIC data file($fpath)", E_USER_WARNING);
    return false;
    }

    fseek($fd, 0, SEEK_SET);
    $tmp = unpack('a4flag/Vinum', fread($fd, 8));
    fseek($fd, $tmp['inum'] * 12 + 8, SEEK_SET);
    $buf = fread($fd, 12);
    if ($tmp['flag'] != 'CTIP' || strlen($buf) != 12)
    {
    fclose($fd);
    trigger_error("Invalid MIC data file($fpath)", E_USER_WARNING);
    return false;
    }
    $this->close();
    $this->fd = $fd;
    $this->flag = $tmp['flag'];
    $this->inum = $tmp['inum'];
    $this->off1 = $tmp['inum'] * 12 + 20;

    $tmp = unpack('V3', $buf);
    $this->off2 = $this->off1 + $tmp[2];
    $this->chrono = $tmp[3];
    return true;
    } function close()
    {
    if ($this->fd) fclose($this->fd);
    $this->fd = false;
    } function query($ip)
    {
    // check the IP
    $ip0 = ip2long($ip);
    if ($ip0 === false || $ip0 === -1)
    {
    $ip0 = gethostbyname($ip0);
    if (!$ip0 || !($ip0 = ip2long($ip0)) || $ip0 == -1)
    {
    trigger_error("Invalid IP Address($ip)", E_USER_WARNING);
    return false;
    }
    } // check the FD
    if (!$this->fd && !$this->open())
    return false; // Binary search
    $ip0 = (float) sprintf('%u', $ip0);
    $low = 0;
    $high = $this->inum - 1;
    $ret = false;
    while ($low <= $high)
    {
    $mid = ($low+$high)>>1;
    $off = $mid * 12 + 8;
    fseek($this->fd, $off, SEEK_SET);
    $buf = fread($this->fd, 16);
    if (strlen($buf) != 16) break;
    $tmp = unpack('V4', $buf);
    if ($tmp[1] < 0) $tmp[1] = (float) sprintf('%u', $tmp[1]);
    if ($tmp[4] < 0) $tmp[4] = (float) sprintf('%u', $tmp[4]); // compare them
    if ($ip0 < $tmp[1])
    {
    // smaller
    $high = $mid - 1;
    }
    else if ($ip0 >= $tmp[4])
    {
    // bigger
    $low = $mid + 1;
    }
    else
    {
    // matched
    $ret = array(NULL, NULL);
    if ($tmp[2] >= 0)
    {
    fseek($this->fd, $this->off1 + $tmp[2], SEEK_SET);
    $vlen = ord(fread($this->fd, 1));
    if ($vlen > 0) $ret[0] = fread($this->fd, $vlen);
    } if ($tmp[3] >= 0)
    {
    fseek($this->fd, $this->off2 + $tmp[3], SEEK_SET);
    $vlen = ord(fread($this->fd, 1));
    if ($vlen > 0) $ret[1] = fread($this->fd, $vlen);
    }
    break;
    }
    }
    return $ret;
    } function version()
    {
    // check the FD
    if (!$this->fd && !$this->open())
    return false; $version = sprintf('%s(Records Num = %d , Date = %s)', 
    $this->flag, $this->inum, date('Y-m-d H:i:s', $this->chrono));
    return $version;
    }
    }
    // Usage:  
    //
    // require 'MIC_query.inc.php';
    // $mic = new MIC_query('mic.dat');
    // $mic->open('/path/to/datafile');
    // $ret = $mic->query('210.32.157.3');
    // print_r($ret);
    // NOT FOUND: return false
    // Mathced: returnn array(<AREA1>, <AREA2>);
    //
    // $mic = & MIC_query::open();
    // $mic->close();