就算用数据库也要把记录读出来插入数据库里 然后查询 大于 >formip 小于 <toip; 这样可行 但是 我现在就像用PHP 实现下 折半查找的算法 ,但是 感觉对于递归的支持 是不是PHP 不行 还是 我写法有问题?

解决方案 »

  1.   

    <?php
    header('Content-Type:text/html; charset=utf-8');ini_set('max_execution_time',0);
    ini_set('memory_limit',-1);$fp = null;function reverse(&$in)
    {
    $out ='';
    $len = strlen($in);
    while ($len>0) 
    {
    $out.=$in[$len-2].$in[$len-1];
    $len -=2;
    }
    return $out;
    }function getip($in)
    {
    $len = strlen($in);
    $dot = '';
    while ($len>0) 
    {
    $out.=$dot.hexdec($in[$len-2].$in[$len-1]);
    $len -=2;
    $dot = '.';
    }
    return $out;
    }function get_offset_data($offset,$format ='H*')
    {
    global $fp;
    fseek($fp,hexdec($offset));
    $data = fread($fp,8);
    $data = unpack($format,$data);
    return $data;
    }//获得索引偏移数据
    function get_data(&$index)
    {
    global $fp;
    foreach ($index as $offset =>$data)
    {
    $data = get_offset_data($data['offset'],'H8IPTO/H8OFFSET');
    //$index[$offset]['ipto'] = getip($data['IPTO']);
    $index[$offset]['ipto'] = reverse($data['IPTO']);
    $index[$offset]['data'] = $data['OFFSET'];
    }
    }
    function get_index($limit = 0)
    {
    global $fp;
    $fp = fopen('Coralwry.dat','rb');
    $index_start = fread($fp,4);
    $index_end = fread($fp,4);

    $index_start = unpack('H*',$index_start);
    $index_start = $index_start[1];
    $index_end = unpack('H*',$index_end);
    $index_end = $index_end[1];

    $index_start = reverse($index_start);
    $index_end = reverse($index_end);

    $limit?$limit:$limit=(hexdec($index_end)-hexdec($index_start))/7+1;
    fseek($fp,hexdec($index_start));
    $i = 1;
    while ($i <= $limit) 
    {

    $seek = ftell($fp);
    $data = fread($fp,7);

    $data = unpack('H8IP/H6OFFSET',$data);
    $index[reverse($data['IP'])] = array('ipfrom'=>reverse($data['IP']),'offset'=>reverse($data['OFFSET']));
    $i++;
    }
    return $index;
    }
    function get_mode_data(&$index,$offset,$aboffset,$type)
    {
    global $fp;
    switch ($type)
    {
    case 1:
    {
    //模式1下 有 3种
    fseek($fp,hexdec($aboffset));
    $tag = fgetc($fp);
    //2级跳转 可能?国家偏移+地区数据 国家偏移+地区偏移?
    if($tag == chr(2))
    {
    $countryoffset = fread($fp,3);
    $curfp = ftell($fp);
    $countryoffset = unpack('H*',$countryoffset);
    $countryoffset = hexdec(reverse($countryoffset[1]));
    $index[$offset]['country'] = get_country($countryoffset);


    $areaoffset = $curfp;
    $index[$offset]['location'] = get_area($areaoffset);

    }
    //地区数据跟在国家数据之后 无任何偏移跳转
    else 
    {
    fseek($fp,-1,SEEK_CUR);
    $countryoffset = ftell($fp);
    $index[$offset]['country'] = get_country($countryoffset);
    //模式2下 地区记录在索引偏移数据之后 可能有2级跳转
    $areaoffset = ftell($fp);
    $index[$offset]['location'] = get_area($areaoffset);
    }
    break;
    }
    case 2:
    {
    //模式2下 $aboffset 为国家 绝对偏移
    $countryoffset = hexdec($aboffset);
    $index[$offset]['country'] = get_country($countryoffset);
    //模式2下 地区记录在索引偏移数据之后 可能有2级跳转
    $areaoffset = hexdec($index[$offset]['offset'])+8;
    $index[$offset]['location'] = get_area($areaoffset);
    break;
    }
    default:
    {
    break;
    }
    }
    }function get_country($countryoffset)
    {
    global $fp;

    fseek($fp,$countryoffset);
    $str = $c = '';
    while ($c!=="\0") 
    {
    $c = fgetc($fp);
    $str .=$c; 
    }
    return iconv('GBK','UTF-8',$str);}function get_area($areaoffset)
    {
    global $fp;

    fseek($fp,$areaoffset);
    $str = $c = $tag = fgetc($fp);
    while ($c!=="00") 
    {
    $c = fread($fp,1);
    $c = unpack('H*',$c);
    $c = $c[1];
    $tag == chr(2)?$str .=$c:$str .=chr(hexdec($c));
    }
    if($tag==chr(1))
    {
    echo '01开头...';
    exit();
    }
    if($tag!==chr(2))
    {
    return iconv('GBK','UTF-8',$str);
    }
    else 
    {
    $areaoffset = hexdec(reverse(substr($str,1)));
    return get_area($areaoffset,$type);
    }

    }function get_location_info(&$index,$offset)
    {
    global $fp;
    $data = $index[$offset];
    $tag = substr($data['data'],0,2);
    $aboffset = reverse(substr($data['data'],2));

    switch ($tag)
    {
    case '01':
    {
    get_mode_data(&$index,$offset,$aboffset,1);
    break;
    }
    case '02':
    {
    get_mode_data(&$index,$offset,$aboffset,2);
    break;
    }
    default:
    {
    $countryoffset = hexdec($index[$offset]['offset'])+4;
    $index[$offset]['country'] = get_country($countryoffset);
    //模式2下 地区记录在索引偏移数据之后 可能有2级跳转
    $areaoffset = ftell($fp);
    $index[$offset]['location'] = get_area($areaoffset);;
    }
    }

    }
    //第一步:入库时开启下面2段就可
    //$index = get_index(334488);
    //get_data(&$index);//echo '<pre>';
    //var_dump($index);
    //echo '</pre>';//获得IP索引数组 找出相对索引偏移
    //$search_index = array_keys($index);
    //echo '<pre>';
    //var_dump($search_index);
    //echo '</pre>';
    $i = 1;
    function get_offset($ip,$min,$max)
    {
    global $num,$search_index;
    if($min < $max)
    {
    $mid = intval(($min+$max)/2);
    $num = $mid;
    }
    else 
    {
    return $mid;
    }
    if(hexdec($search_index[$mid]) == $ip)
    {
    return $mid;
    }
    elseif(hexdec($search_index[$mid]) > $ip)
    {
    get_offset($ip,$min,$mid);
    }
    else 
    {
    get_offset($ip,$mid,$max);
    }
    }//
    //$offset = '01000000';
    //get_location_info(&$index,$offset);
    //
    //echo '<pre>';
    //var_dump($index[$offset]);
    //echo '</pre>';//第二步:开启下面sql
    //$connect = mysql_connect('localhost','root','mnky3cr5') or die('ss');
    //$db = mysql_select_db('ip',$connect);
    //foreach ($index as $offset =>$info)
    //{
    //mysql_query('insert into ip(`id`,`ipfrom`,`ipto`,`offset`,`data`) values(NULL,"'.$info['ipfrom'].'","'.$info['ipto'].'","'.$info['offset'].'","'.$info['data'].'")');
    //}
    //exit();
    $index = null;
    $offset = null;
    $fp = fopen('Coralwry.dat','rb');
    get_location('192.168.1.1');
    get_location('192.168.1.1');
    function get_location($ip)
    {
    global $index,$offset;
    if(preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/',$ip))
    {
    $ip = split('\.',$ip);
    $ip = sprintf('%02X',$ip[0]).sprintf('%02X',$ip[1]).sprintf('%02X',$ip[2]).sprintf('%02X',$ip[3]);
    $connect = mysql_connect('localhost','root','mnky3cr5') or die('ss');
    $db = mysql_select_db('ip',$connect);
    $result = mysql_query('SELECT ipfrom,ipto,offset,data FROM ip WHERE ipfrom<"'.$ip .'" AND ipto >"'.$ip.'"');
    echo 'SELECT ipfrom,ipto,offset,data FROM ip WHERE ipfrom<"'.$ip .'" AND ipto >"'.$ip.'"';
    while (false !=($data = mysql_fetch_assoc($result))) 
    {
    $offset = $data['ipfrom'];
    $index[$offset] = $data;
    // echo '<pre>';
    // var_dump($index);
    // echo '</pre>';


    get_location_info(&$index,$offset);

    $index[$offset]['ipfrom'] = getip(reverse($index[$offset]['ipfrom']));
    $index[$offset]['ipto'] = getip(reverse($index[$offset]['ipto']));
    echo '<pre>';
    var_dump($index);
    echo '</pre>';
    }
    }
    else 
    {
    echo 'IP 不合法~';
    }
    }?>
     //这个是用数据库实现的 .没意思
      

  2.   

    用数据库...哎..<?php
    header('Content-Type:text/html; charset=utf-8');ini_set('max_execution_time',0);
    ini_set('memory_limit',-1);$fp = null;
    if(!$_GET['ip'])
    {
    ?>
    <form method="GET">
    <input name="ip" type="text">
    <input type="submit" name="search" value="search" />
    </form><?php
    exit();
    }
    function reverse(&$in)
    {
    $out ='';
    $len = strlen($in);
    while ($len>0) 
    {
    $out.=$in[$len-2].$in[$len-1];
    $len -=2;
    }
    return $out;
    }function getip($in)
    {
    $len = strlen($in);
    $dot = '';
    while ($len>0) 
    {
    $out.=$dot.hexdec($in[$len-2].$in[$len-1]);
    $len -=2;
    $dot = '.';
    }
    return $out;
    }function get_offset_data($offset,$format ='H*')
    {
    global $fp;
    fseek($fp,hexdec($offset));
    $data = fread($fp,8);
    $data = unpack($format,$data);
    return $data;
    }//获得索引偏移数据
    function get_data(&$index)
    {
    global $fp;
    foreach ($index as $offset =>$data)
    {
    $data = get_offset_data($data['offset'],'H8IPTO/H8OFFSET');
    //$index[$offset]['ipto'] = getip($data['IPTO']);
    $index[$offset]['ipto'] = reverse($data['IPTO']);
    $index[$offset]['data'] = $data['OFFSET'];
    }
    }
    function get_index($limit = 0)
    {
    global $fp;
    $fp = fopen('Coralwry.dat','rb');
    $index_start = fread($fp,4);
    $index_end = fread($fp,4);

    $index_start = unpack('H*',$index_start);
    $index_start = $index_start[1];
    $index_end = unpack('H*',$index_end);
    $index_end = $index_end[1];

    $index_start = reverse($index_start);
    $index_end = reverse($index_end);

    $limit?$limit:$limit=(hexdec($index_end)-hexdec($index_start))/7+1;
    fseek($fp,hexdec($index_start));
    $i = 1;
    while ($i <= $limit) 
    {

    $seek = ftell($fp);
    $data = fread($fp,7);

    $data = unpack('H8IP/H6OFFSET',$data);
    $index[reverse($data['IP'])] = array('ipfrom'=>reverse($data['IP']),'offset'=>reverse($data['OFFSET']));
    $i++;
    }
    return $index;
    }
    function get_mode_data(&$index,$offset,$aboffset,$type)
    {
    global $fp;

    switch ($type)
    {
    case 1:
    {
    //模式1下 有 3种

    echo '<br />模式一:读取信息 偏移';
    echo $aboffset;
    fseek($fp,hexdec($aboffset));
    $tag = fgetc($fp);
    //2级跳转 可能?国家偏移+地区数据 国家偏移+地区偏移?
    if($tag == chr(2))
    {
    $countryoffset = fread($fp,3);
    $curfp = ftell($fp);
    $countryoffset = unpack('H*',$countryoffset);
    $countryoffset = hexdec(reverse($countryoffset[1]));
    $index[$offset]['country'] = get_country($countryoffset);


    $areaoffset = $curfp;
    $index[$offset]['location'] = get_area($areaoffset);

    }
    //地区数据跟在国家数据之后 无任何偏移跳转
    else 
    {
    fseek($fp,-1,SEEK_CUR);
    $countryoffset = ftell($fp);
    $index[$offset]['country'] = get_country($countryoffset);
    //模式2下 地区记录在索引偏移数据之后 可能有2级跳转
    $areaoffset = ftell($fp);
    $index[$offset]['location'] = get_area($areaoffset);
    }
    break;
    }
    case 2:
    {
    //模式2下 $aboffset 为国家 绝对偏移

    echo '<br />模式二:读取信息 偏移';
    echo $aboffset;
    $countryoffset = hexdec($aboffset);
    $index[$offset]['country'] = get_country($countryoffset);
    //模式2下 地区记录在索引偏移数据之后 可能有2级跳转
    $areaoffset = hexdec($index[$offset]['offset'])+8;
    $index[$offset]['location'] = get_area($areaoffset);
    break;
    }
    default:
    {
    break;
    }
    }
    }function get_country($countryoffset)
    {
    global $fp;
    echo '<br />读取一级国家/地区信息 偏移:';
    echo strtoupper(dechex($countryoffset));
    fseek($fp,$countryoffset);
    $str = $c = '';
    while ($c!=="\0") 
    {
    $c = fgetc($fp);
    $str .=$c; 
    }
    echo '<br />记录信息:'.iconv('GBK','UTF-8',$str);
    return iconv('GBK','UTF-8',$str);}function get_area($areaoffset)
    {
    global $fp;

    echo '<br />读取二级地区/网络信息 偏移:';
    echo strtoupper(dechex($areaoffset));

    fseek($fp,$areaoffset);
    $str = $c = $tag = fgetc($fp);
    if($tag==chr(1))
    {
    echo '01开头...';
    exit();
    }
    if($tag!==chr(2))
    {
    while ($c!=="00") 
    {
    $c = fread($fp,1);
    $c = unpack('H*',$c);
    $c = $c[1];
    $str .=chr(hexdec($c));
    }

    echo '<br />记录信息:'.iconv('GBK','UTF-8',$str);
    return iconv('GBK','UTF-8',$str);
    }
    else 
    {
    echo '<br />重定向读取二级地区/网络信息 偏移:';
    echo strtoupper(dechex($areaoffset));

    $areaoffset = fread($fp,3);
    $curfp = ftell($fp);
    $areaoffset = unpack('H*',$areaoffset);
    $areaoffset = hexdec(reverse($areaoffset[1]));
    return get_area($areaoffset);
    }

    }function get_location_info(&$index,$offset)
    {
    global $fp;
    $data = $index[$offset];
    $tag = substr($data['data'],0,2);
    //01 010ff6
    $aboffset = reverse(substr($data['data'],2));

    switch ($tag)
    {
    case '01':
    {
    get_mode_data(&$index,$offset,$aboffset,1);
    break;
    }
    case '02':
    {
    get_mode_data(&$index,$offset,$aboffset,2);
    break;
    }
    default:
    {

    echo '<br />默认模式:';
    $countryoffset = hexdec($index[$offset]['offset'])+4;
    $index[$offset]['country'] = get_country($countryoffset);
    //模式2下 地区记录在索引偏移数据之后 可能有2级跳转
    $areaoffset = ftell($fp);
    $index[$offset]['location'] = get_area($areaoffset);;
    }
    }

    }
    //第一步:入库时开启下面2段就可
    //$index = get_index(1000);
    //get_data(&$index);
    //
    //echo '<pre>';
    //var_dump($index);
    //echo '</pre>';//获得IP索引数组 找出相对索引偏移
    //$search_index = array_keys($index);
    //echo '<pre>';
    //var_dump($search_index);
    //echo '</pre>';
    function get_offset($ip,$min,$max)
    {
    global $num,$search_index;
    if($min < $max)
    {
    $mid = intval(($min+$max)/2);
    $num = $mid;
    }
    else 
    {
    return $mid;
    }
    if(hexdec($search_index[$mid]) == $ip)
    {
    return $mid;
    }
    elseif(hexdec($search_index[$mid]) > $ip)
    {
    get_offset($ip,$min,$mid);
    }
    else 
    {
    get_offset($ip,$mid,$max);
    }
    }//
    //$offset = '01000000';
    //get_location_info(&$index,$offset);
    //
    //echo '<pre>';
    //var_dump($index[$offset]);
    //echo '</pre>';//第二步:开启下面sql
    //$connect = mysql_connect('localhost','root','mnky3cr5') or die('ss');
    //$db = mysql_select_db('ip',$connect);
    //foreach ($index as $offset =>$info)
    //{
    //mysql_query('insert into ip(`id`,`ipfrom`,`ipto`,`offset`,`data`) values(NULL,"'.$info['ipfrom'].'","'.$info['ipto'].'","'.$info['offset'].'","'.$info['data'].'")');
    //}
    //exit();
    $index = null;
    $offset = null;
    $fp = fopen('Coralwry.dat','rb');
    get_location($_GET['ip']);
    function get_location($ip)
    {
    global $index,$offset;
    if(preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/',$ip))
    {
    $ip = split('\.',$ip);
    $ip = sprintf('%02X',$ip[0]).sprintf('%02X',$ip[1]).sprintf('%02X',$ip[2]).sprintf('%02X',$ip[3]);
    $connect = mysql_connect('localhost','root','mnky3cr5') or die('ss');
    $db = mysql_select_db('ip',$connect);
    $result = mysql_query('SELECT ipfrom,ipto,offset,data FROM ip WHERE ipfrom<"'.$ip .'" AND ipto >"'.$ip.'" OR ipfrom="'.$ip .'" OR ipto ="'.$ip.'"');
    //echo 'SELECT ipfrom,ipto,offset,data FROM ip WHERE ipfrom<"'.$ip .'" AND ipto >"'.$ip.'" OR ipfrom="'.$ip .'" OR ipto ="'.$ip.'"';
    while (false !=($data = mysql_fetch_assoc($result))) 
    {
    $offset = $data['ipfrom'];
    $index[$offset] = $data;
    // echo '<pre>';
    // var_dump($index);
    // echo '</pre>';


    get_location_info(&$index,$offset);

    $index[$offset]['ipfrom'] = getip(reverse($data['ipfrom']));
    $index[$offset]['ipto'] = getip(reverse($data['ipto']));
    echo '<pre>';
    var_dump($index);
    echo '</pre>';
    }
    }
    else 
    {
    echo 'IP 不合法~';
    }
    }?>