显示IP真实地址

    /*  
     * $Id: ipLocation.class.php v0.0.1 2008-11-4 Linvo $  
     * $author: www.phperz.com  
     * Copyright(C) 2008  
     */    
    class ipLocation {    
        var $fp;    
        var $firstip;   //第一条ip索引的偏移地址    
        var $lastip;    //最后一条ip索引的偏移地址    
        var $totalip;   //总ip数    
       
        //*    
        //构造函数,初始化一些变量    
        //$datfile 的值为纯真IP数据库的名子,可自行修改.    
        //*    
        function ipLocation($datfile = 'IPdb.Dat')    
        {    
            $this->fp = fopen($datfile,'rb');   //二制方式打开    
            $this->firstip  = $this->get4b();   //第一条ip索引的绝对偏移地址    
            $this->lastip   = $this->get4b();   //最后一条ip索引的绝对偏移地址    
            $this->totalip  = ($this->lastip - $this->firstip)/7 ;  //ip总数 索引区是定长的7个字节,在此要除以7,     
            register_shutdown_function(array($this,'closefp'));     //为了兼容php5以下版本,本类没有用析构函数,自动关闭ip库.    
        }    
       
        //*    
        //关闭ip库    
        //*    
        function closefp()    
        {    
            fclose($this->fp);    
        }    
       
        //*    
        //读取4个字节并将解压成long的长模式    
        //*    
        function get4b()    
        {    
            $str = unpack('V', fread($this->fp, 4));    
            return $str[1];    
        }    
       
        //*    
        //读取重定向了的偏移地址    
        //*    
        function getoffset()    
        {    
            $str = unpack('V', fread($this->fp, 3).chr(0));    
            return $str[1];    
        }    
       
        //*    
        //读取ip的详细地址信息    
        //*    
        function getstr()    
        {    
            $split = fread($this->fp, 1);    
            while(ord($split) != 0)    
            {    
                $str .= $split;    
                $split = fread($this->fp,1);    
            }    
            return $str;    
        }    
       
        //*    
        //将ip通过ip2long转成ipv4的互联网地址,再将他压缩成big-endian字节序    
        //用来和索引区内的ip地址做比较    
        //*    
        function iptoint($ip)    
        {    
            return pack('N', intval(ip2long($ip)));    
        }    
       
        //*    
        //获取地址信息    
        //*    
        function readaddress()    
        {    
            $now_offset = ftell($this->fp); //得到当前的指针位址    
            $flag = $this->getflag();    
            switch(ord($flag))    
            {    
            case 0:     
                $address = '';    
                break;    
            case 1:    
            case 2:    
                fseek($this->fp, $this->getoffset());    
                $address = $this->getstr();    
                break;    
            default:    
                fseek($this->fp, $now_offset);    
                $address = $this->getstr();    
                break;    
            }    
            return $address;    
        }    
       
        //*    
        //获取标志1或2    
        //用来确定地址是否重定向了.    
        //*    
        function getflag()    
        {    
            return fread($this->fp, 1);    
        }    
       
        //*    
        //用二分查找法在索引区内搜索ip    
        //*    
        function searchip($ip)    
        {    
            $ip = gethostbyname($ip);     //将域名转成ip    
            $ip_offset['ip'] = $ip;    
            $ip = $this->iptoint($ip);    //将ip转换成长整型    
            $firstip = 0;                 //搜索的上边界    
            $lastip = $this->totalip;     //搜索的下边界    
            $ipoffset = $this->lastip;    //初始化为最后一条ip地址的偏移地址    
            while($firstip <= $lastip)    
            {    
                $i = floor(($firstip + $lastip) / 2);       //计算近似中间记录 floor函数记算给定浮点数小的最大整数,说白了就是四舍五也舍    
                fseek($this->fp, $this->firstip + $i * 7);  //定位指针到中间记录    
                $startip = strrev(fread($this->fp, 4));     //读取当前索引区内的开始ip地址,并将其little-endian的字节序转换成big-endian的字节序 php程序员站     
                if($ip < $startip)    
                {    
                    $lastip = $i - 1;    
                }else{    
                    fseek($this->fp, $this->getoffset());    
                    $endip = strrev(fread($this->fp, 4));    
                    if ($ip > $endip){    
                       $firstip = $i + 1;    
                    }else{    
                       $ip_offset['offset'] = $this->firstip + $i * 7;    
                       break;    
                    }    
                }    
            }    
            return $ip_offset;    
        }    
       
        //*    
        //获取ip地址详细信息    
        //*    
        function getaddress($ip)    
        {    
            $ip_offset = $this->searchip($ip);              //获取ip 在索引区内的绝对编移地址    
            $ipoffset = $ip_offset['offset'];    
            $address['ip'] = $ip_offset['ip'];    
            fseek($this->fp, $ipoffset);                    //定位到索引区    
            $address['startip'] = long2ip($this->get4b());  //索引区内的开始ip 地址      
            $address_offset = $this->getoffset();           //获取索引区内ip在ip记录区内的偏移地址    
            fseek($this->fp, $address_offset);              //定位到记录区内    
            $address['endip'] = long2ip($this->get4b());    //记录区内的结束ip 地址    
            $flag = $this->getflag();                       //读取标志字节    
            switch(ord($flag))    
            {    
            case 1: //地区1地区2都重定向    
                $address_offset = $this->getoffset();       //读取重定向地址    
                fseek($this->fp, $address_offset);          //定位指针到重定向的地址    
                $flag = $this->getflag();                   //读取标志字节    
                switch(ord($flag))    
                {    
                case 2: //地区1又一次重定向,    
                    fseek($this->fp, $this->getoffset());    
                    $address['area1'] = $this->getstr();    
                    fseek($this->fp, $address_offset+4);        //跳4个字节    
                    $address['area2'] = $this->readaddress();   //地区2有可能重定向,有可能没有    
                    break;    
                default: //地区1,地区2都没有重定向    
                    fseek($this->fp, $address_offset);          //定位指针到重定向的地址    
                    $address['area1'] = $this->getstr();    
                    $address['area2'] = $this->readaddress();    
                    break;    
                }    
               break;    
            case 2: //地区1重定向 地区2没有重定向    
               $address1_offset = $this->getoffset();   //读取重定向地址    
               fseek($this->fp, $address1_offset);     
               $address['area1'] = $this->getstr();    
               fseek($this->fp, $address_offset+8);    
               $address['area2'] = $this->readaddress();    
               break;    
            default: //地区1地区2都没有重定向    
               fseek($this->fp, $address_offset+4);    
               $address['area1'] = $this->getstr();    
               $address['area2'] = $this->readaddress();    
               break;    
            }    
       
            //*过滤一些无用数据    
            if(strpos($address['area1'], 'CZ88.NET') != false)  $address['area1'] = '未知';    
            if(strpos($address['area2'], 'CZ88.NET') != false)  $address['area2'] = ' ';    
            return $address;    
        }    
       
    }    
     调用测试文件:test.php  
       
    PHP代码  
    header("content-type:text/html;charset=utf-8");    
       
    include 'ipLocation.class.php'; //载入类    
       
    $ip_1 = '218.198.33.3';    
    $ip_2 = '127.0.0.1';    
       
    $myobj  =new ipLocation();    
       
    $address = $myobj->getaddress($ip_1);    
    echo iconv('gb2312','utf-8',$address['area1'].' '.$address['area2']).'<br />';    
    //输出:河南省郑州市 郑州大学升达经贸管理学院    
       
    $address = $myobj->getaddress($ip_2);    
    echo iconv('gb2312','utf-8',$address['area1'].' '.$address['area2']).'<br />';    
    //输出:本机地址  

转自http://blog.csdn.net/linvo/article/details/3893485

  1. /*  
  2.  * $Id: ipLocation.class.php v0.0.1 2008-11-4 Linvo $  
  3.  * $author: www.phperz.com  
  4.  * Copyright(C) 2008  
  5.  */    
  6. class ipLocation {    
  7.     var $fp;    
  8.     var $firstip;   //第一条ip索引的偏移地址    
  9.     var $lastip;    //最后一条ip索引的偏移地址    
  10.     var $totalip;   //总ip数    
  11.    
  12.     //*    
  13.     //构造函数,初始化一些变量    
  14.     //$datfile 的值为纯真IP数据库的名子,可自行修改.    
  15.     //*    
  16.     function ipLocation($datfile = 'IPdb.Dat')    
  17.     {    
  18.         $this->fp = fopen($datfile,'rb');   //二制方式打开    
  19.         $this->firstip  = $this->get4b();   //第一条ip索引的绝对偏移地址    
  20.         $this->lastip   = $this->get4b();   //最后一条ip索引的绝对偏移地址    
  21.         $this->totalip  = ($this->lastip - $this->firstip)/7 ;  //ip总数 索引区是定长的7个字节,在此要除以7,     
  22.         register_shutdown_function(array($this,'closefp'));     //为了兼容php5以下版本,本类没有用析构函数,自动关闭ip库.    
  23.     }    
  24.    
  25.     //*    
  26.     //关闭ip库    
  27.     //*    
  28.     function closefp()    
  29.     {    
  30.         fclose($this->fp);    
  31.     }    
  32.    
  33.     //*    
  34.     //读取4个字节并将解压成long的长模式    
  35.     //*    
  36.     function get4b()    
  37.     {    
  38.         $str = unpack('V'fread($this->fp, 4));    
  39.         return $str[1];    
  40.     }    
  41.    
  42.     //*    
  43.     //读取重定向了的偏移地址    
  44.     //*    
  45.     function getoffset()    
  46.     {    
  47.         $str = unpack('V'fread($this->fp, 3).chr(0));    
  48.         return $str[1];    
  49.     }    
  50.    
  51.     //*    
  52.     //读取ip的详细地址信息    
  53.     //*    
  54.     function getstr()    
  55.     {    
  56.         $split = fread($this->fp, 1);    
  57.         while(ord($split) != 0)    
  58.         {    
  59.             $str .= $split;    
  60.             $split = fread($this->fp,1);    
  61.         }    
  62.         return $str;    
  63.     }    
  64.    
  65.     //*    
  66.     //将ip通过ip2long转成ipv4的互联网地址,再将他压缩成big-endian字节序    
  67.     //用来和索引区内的ip地址做比较    
  68.     //*    
  69.     function iptoint($ip)    
  70.     {    
  71.         return pack('N'intval(ip2long($ip)));    
  72.     }    
  73.    
  74.     //*    
  75.     //获取地址信息    
  76.     //*    
  77.     function readaddress()    
  78.     {    
  79.         $now_offset = ftell($this->fp); //得到当前的指针位址    
  80.         $flag = $this->getflag();    
  81.         switch(ord($flag))    
  82.         {    
  83.         case 0:     
  84.             $address = '';    
  85.             break;    
  86.         case 1:    
  87.         case 2:    
  88.             fseek($this->fp, $this->getoffset());    
  89.             $address = $this->getstr();    
  90.             break;    
  91.         default:    
  92.             fseek($this->fp, $now_offset);    
  93.             $address = $this->getstr();    
  94.             break;    
  95.         }    
  96.         return $address;    
  97.     }    
  98.    
  99.     //*    
  100.     //获取标志1或2    
  101.     //用来确定地址是否重定向了.    
  102.     //*    
  103.     function getflag()    
  104.     {    
  105.         return fread($this->fp, 1);    
  106.     }    
  107.    
  108.     //*    
  109.     //用二分查找法在索引区内搜索ip    
  110.     //*    
  111.     function searchip($ip)    
  112.     {    
  113.         $ip = gethostbyname($ip);     //将域名转成ip    
  114.         $ip_offset['ip'] = $ip;    
  115.         $ip = $this->iptoint($ip);    //将ip转换成长整型    
  116.         $firstip = 0;                 //搜索的上边界    
  117.         $lastip = $this->totalip;     //搜索的下边界    
  118.         $ipoffset = $this->lastip;    //初始化为最后一条ip地址的偏移地址    
  119.         while($firstip <= $lastip)    
  120.         {    
  121.             $i = floor(($firstip + $lastip) / 2);       //计算近似中间记录 floor函数记算给定浮点数小的最大整数,说白了就是四舍五也舍    
  122.             fseek($this->fp, $this->firstip + $i * 7);  //定位指针到中间记录    
  123.             $startip = strrev(fread($this->fp, 4));     //读取当前索引区内的开始ip地址,并将其little-endian的字节序转换成big-endian的字节序 php程序员站     
  124.             if($ip < $startip)    
  125.             {    
  126.                 $lastip = $i - 1;    
  127.             }else{    
  128.                 fseek($this->fp, $this->getoffset());    
  129.                 $endip = strrev(fread($this->fp, 4));    
  130.                 if ($ip > $endip){    
  131.                    $firstip = $i + 1;    
  132.                 }else{    
  133.                    $ip_offset['offset'] = $this->firstip + $i * 7;    
  134.                    break;    
  135.                 }    
  136.             }    
  137.         }    
  138.         return $ip_offset;    
  139.     }    
  140.    
  141.     //*    
  142.     //获取ip地址详细信息    
  143.     //*    
  144.     function getaddress($ip)    
  145.     {    
  146.         $ip_offset = $this->searchip($ip);              //获取ip 在索引区内的绝对编移地址    
  147.         $ipoffset = $ip_offset['offset'];    
  148.         $address['ip'] = $ip_offset['ip'];    
  149.         fseek($this->fp, $ipoffset);                    //定位到索引区    
  150.         $address['startip'] = long2ip($this->get4b());  //索引区内的开始ip 地址      
  151.         $address_offset = $this->getoffset();           //获取索引区内ip在ip记录区内的偏移地址    
  152.         fseek($this->fp, $address_offset);              //定位到记录区内    
  153.         $address['endip'] = long2ip($this->get4b());    //记录区内的结束ip 地址    
  154.         $flag = $this->getflag();                       //读取标志字节    
  155.         switch(ord($flag))    
  156.         {    
  157.         case 1: //地区1地区2都重定向    
  158.             $address_offset = $this->getoffset();       //读取重定向地址    
  159.             fseek($this->fp, $address_offset);          //定位指针到重定向的地址    
  160.             $flag = $this->getflag();                   //读取标志字节    
  161.             switch(ord($flag))    
  162.             {    
  163.             case 2: //地区1又一次重定向,    
  164.                 fseek($this->fp, $this->getoffset());    
  165.                 $address['area1'] = $this->getstr();    
  166.                 fseek($this->fp, $address_offset+4);        //跳4个字节    
  167.                 $address['area2'] = $this->readaddress();   //地区2有可能重定向,有可能没有    
  168.                 break;    
  169.             default//地区1,地区2都没有重定向    
  170.                 fseek($this->fp, $address_offset);          //定位指针到重定向的地址    
  171.                 $address['area1'] = $this->getstr();    
  172.                 $address['area2'] = $this->readaddress();    
  173.                 break;    
  174.             }    
  175.            break;    
  176.         case 2: //地区1重定向 地区2没有重定向    
  177.            $address1_offset = $this->getoffset();   //读取重定向地址    
  178.            fseek($this->fp, $address1_offset);     
  179.            $address['area1'] = $this->getstr();    
  180.            fseek($this->fp, $address_offset+8);    
  181.            $address['area2'] = $this->readaddress();    
  182.            break;    
  183.         default//地区1地区2都没有重定向    
  184.            fseek($this->fp, $address_offset+4);    
  185.            $address['area1'] = $this->getstr();    
  186.            $address['area2'] = $this->readaddress();    
  187.            break;    
  188.         }    
  189.    
  190.         //*过滤一些无用数据    
  191.         if(strpos($address['area1'], 'CZ88.NET') != false)  $address['area1'] = '未知';    
  192.         if(strpos($address['area2'], 'CZ88.NET') != false)  $address['area2'] = ' ';    
  193.         return $address;    
  194.     }    
  195.    
  196. }    
  197.  调用测试文件:test.php  
  198.    
  199. PHP代码  
  200. header("content-type:text/html;charset=utf-8");    
  201.    
  202. include 'ipLocation.class.php'//载入类    
  203.    
  204. $ip_1 = '218.198.33.3';    
  205. $ip_2 = '127.0.0.1';    
  206.    
  207. $myobj  =new ipLocation();    
  208.    
  209. $address = $myobj->getaddress($ip_1);    
  210. echo iconv('gb2312','utf-8',$address['area1'].' '.$address['area2']).'<br />';    
  211. //输出:河南省郑州市 郑州大学升达经贸管理学院    
  212.    
  213. $address = $myobj->getaddress($ip_2);    
  214. echo iconv('gb2312','utf-8',$address['area1'].' '.$address['area2']).'<br />';    
  215. //输出:本机地址 

posted on 2012-05-28 16:51  kudosharry  阅读(324)  评论(0编辑  收藏  举报

导航