zoukankan      html  css  js  c++  java
  • 纯真IP库读取文件

    <?php
    	
    /**
         * 查IP所在地(需纯真IP数据包)
         * 来自discuz
         */
        function ip2addr($ip) {
            //IP数据文件路径
            $dat_path = SYS_DIR . '/wry.dat';
    
            //检查IP地址
            if (! preg_match ( "/^d{1,3}.d{1,3}.d{1,3}.d{1,3}$/", $ip )) {
                return 'IP Address Error';
            }
            //打开IP数据文件
            if (! $fd = @fopen ( $dat_path, 'rb' )) {
                return 'IP date file not exists or access denied';
            }
    
            //分解IP进行运算,得出整形数
            $ip = explode ( '.', $ip );
            $ipNum = $ip [0] * 16777216 + $ip [1] * 65536 + $ip [2] * 256 + $ip [3];
    
            //获取IP数据索引开始和结束位置
            $DataBegin = fread ( $fd, 4 );
            $DataEnd = fread ( $fd, 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 = 0;
            $ip2num = 0;
            $ipAddr1='';
            $ipAddr2='';
            //使用二分查找法从索引记录中搜索匹配的IP记录
            while ( $ip1num > $ipNum || $ip2num < $ipNum ) {
                $Middle = intval ( ($EndNum + $BeginNum) / 2 );
    
                //偏移指针到索引位置读取4个字节
                fseek ( $fd, $ipbegin + 7 * $Middle );
                $ipData1 = fread ( $fd, 4 );
                if (strlen ( $ipData1 ) < 4) {
                    fclose ( $fd );
                    return 'System Error';
                }
                //提取出来的数据转换成长整形,如果数据是负数则加上2的32次幂
                $ip1num = implode ( '', unpack ( 'L', $ipData1 ) );
                if ($ip1num < 0)
                    $ip1num += pow ( 2, 32 );
    
                //提取的长整型数大于我们IP地址则修改结束位置进行下一次循环
                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';
            }
    
            //转成utf8
            return mb_convert_encoding ( $ipaddr, "utf-8", "gbk" );
        }
    

      

  • 相关阅读:
    Oracle over函数
    如何用 SQL Tuning Advisor (STA) 优化SQL语句
    Oracle SQL的硬解析和软解析
    Oracle执行计划详解
    正则表达式的语法规则
    ArcGIS Runtime for Android开发教程V2.0(3)基础篇---Hello World Map
    ArcGIS Runtime for Android开发教程V2.0(2)开发环境配置
    ArcGIS Runtime for Android开发教程V2.0(1)基本概念
    在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误。
    配置SQL Server 2008服务器
  • 原文地址:https://www.cnblogs.com/icyy/p/5213252.html
Copyright © 2011-2022 走看看