<?php
if(!function_exists('getClientIp')) :
    function getClientIp()
    {
        if (getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
            $ip = getenv('HTTP_CLIENT_IP');
        } elseif (getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {
            $ip = getenv('HTTP_X_FORWARDED_FOR');
        } elseif (getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {
            $ip = getenv('REMOTE_ADDR');
        } elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
            $ip = $_SERVER['REMOTE_ADDR'];
        }
        $ip=preg_match ( '/[\d\.]{7,15}/', $ip, $matches ) ? $matches [0] : '';
        if (!(strpos($ip, '192.168.') === FALSE)) {
            $ip=false;
            if (!empty($_SERVER["HTTP_CLIENT_IP"])) {
                $ip = $_SERVER["HTTP_CLIENT_IP"];
            }
            if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
                $ips = explode (", ", $_SERVER['HTTP_X_FORWARDED_FOR']);
                if ($ip) {
                    array_unshift($ips, $ip); $ip = FALSE;
                }
                for ($i = 0; $i < count($ips); $i++) {
                    if (!eregi ("^(10|172\.16|192\.168)\.", $ips[$i])) {
                        $ip = $ips[$i];
                        break;
                    }
                }
            }
            $ip=$ip ? $ip : $_SERVER['REMOTE_ADDR'];
        }

        return $ip;
    }
endif;

if( !function_exists('chkLocationIpByHttp') ) :
    function chkLocationIpByHttp()
    {
        $ip   = getClientIp();
        $long = API_IP2LONG($ip);
        $url  = 'http://api.apihezi.com/ipbase/index?ip=' . $long;
        $json = cUrlGet($url);
        $data = json_decode($json, true);

        return accessFp($data);
    }
endif;

if( !function_exists('chkLocationIpByDb') ) :
    function chkLocationIpByDb()
    {
        $ip   = getClientIp();
        $long = API_IP2LONG($ip);
        // $url  = 'http://api.apihezi.com/ipbase/index?ip=' . $long;
        // $json = cUrlGet($url);
        // $data = json_decode($json, true);

        // return $data;
    }
endif;

if( !function_exists('accessFp') ):
    function accessFp($return_data_array)
    {
        $check_country=$check_type=$check_services=$check_organization=0; // 默认是0

        if ($return_data_array['errcode']==0) {
            $ip_data_array = $return_data_array['data'];
            //  country
            if ( !empty($ip_data_array['country']) && ((stripos($ip_data_array['country'], 'United States') !== false)
             || (stripos($ip_data_array['country'], 'China') !== false)
             || (stripos($ip_data_array['country'], 'Australia') !== false)
             || (stripos($ip_data_array['country'], 'Singapore') !== false)
             || (stripos($ip_data_array['country'], 'Canada') !== false)
             || (stripos($ip_data_array['country'], 'New Zealand') !== false)
             || (stripos($ip_data_array['country'], 'Spain') !== false)
             || (stripos($ip_data_array['country'], 'Czech Republic') !== false)
             || (stripos($ip_data_array['country'], 'Qatar') !== false)
             || (stripos($ip_data_array['country'], 'Malaysia') !== false)
             || (stripos($ip_data_array['country'], 'United Arab Emirates') !== false)
             || (stripos($ip_data_array['country'], 'Vietnam') !== false)
             || (stripos($ip_data_array['country'], 'Brunei Darussalam') !== false)
             || (stripos($ip_data_array['country'], 'Myanmar') !== false)
             || (stripos($ip_data_array['country'], 'Ireland') !== false)
             || (stripos($ip_data_array['country'], 'Mexico') !== false)) ) {   // find any one set to 1
                $check_country = 1;
            }
            // organization
            if  ( !empty($ip_data_array['organization']) && (stripos($ip_data_array['organization'], 'Facebook') === false)
                 && (stripos($ip_data_array['organization'], 'Google') === false)
                 && (stripos($ip_data_array['organization'], 'Amazon') === false)
                 && (stripos($ip_data_array['organization'], 'Bing') === false)
                 && (stripos($ip_data_array['organization'], 'Microsoft') === false)
                 && (stripos($ip_data_array['organization'], 'PayPal') === false)
                 && (stripos($ip_data_array['organization'], 'eBay') === false)
                 && (stripos($ip_data_array['organization'], 'SoftLayer') === false)
                 && (stripos($ip_data_array['organization'], 'Bharti') === false)
                 && (stripos($ip_data_array['organization'], 'Technologies') === false) )  {    // find nothing set to 1
                    $check_organization = 1;
            }
            // services
            if ( (!empty($ip_data_array['services']) && (stripos($ip_data_array['services'], 'proxy')===false) && (stripos($ip_data_array['services'], 'spam')===false))
                || (stripos($ip_data_array['country'], 'Singapore') !== false) ) {    // find no proxy and no spam set to 1
                $check_services = 1;
            }
            // type
            if ( !empty($ip_data_array['type']) && (stripos($ip_data_array['type'], "Corporate")===false) ) {
            // find no corporate set to 1
               $check_type = 1;
            }

            return ($check_country&&$check_type&&$check_services&&$check_organization==1)?1:0;
        }

        return false;
    }
endif;

if( !function_exists('cUrlGet') ) :
    function cUrlGet($url, $method = 'GET')
    {
        $ch = curl_init();
        $header = "Accept-Charset: utf-8";
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, strtoupper($method));
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array($header));
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
        curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $temp = curl_exec($ch);
        curl_close($ch);

        return $temp;
    }
endif;

if( !function_exists('API_IP2LONG') ) :
    function API_IP2LONG($a)
    {
        $d = 0.0;
        $b = explode(".", $a,4);
        for ($i = 0; $i < 4; $i++) {
            $d *= 256.0;
            $d += $b[$i];
        };

        return $d;
    }
endif;

if( !function_exists('API_LONG2IP') ) :
    function API_LONG2IP($a)
    {
        $b=array(0,0,0,0);
        $c = 16777216.0;
        $a += 0.0;
        for ($i = 0; $i < 4; $i++) {
            $k = (int) ($a / $c);
            $a -= $c * $k;
            $b[$i]= $k;
            $c /=256.0;
        };
        $d=join('.', $b);

        return($d);
    }
endif;

if( !function_exists('isMobile') ) :
    function isMobile()
    {
        // 如果有HTTP_X_WAP_PROFILE则一定是移动设备
        if (isset ($_SERVER['HTTP_X_WAP_PROFILE'])) {
            return true;
        }
        // 如果via信息含有wap则一定是移动设备,部分服务商会屏蔽该信息
        if (isset ($_SERVER['HTTP_VIA'])) {
            // 找不到为flase,否则为true
            return stristr($_SERVER['HTTP_VIA'], "wap") ? true : false;
        }
        // 脑残法，判断手机发送的客户端标志,兼容性有待提高
        if (isset ($_SERVER['HTTP_USER_AGENT'])) {
            $clientkeywords = array ('nokia',
                'sony',
                'ericsson',
                'mot',
                'samsung',
                'htc',
                'sgh',
                'lg',
                'sharp',
                'sie-',
                'philips',
                'panasonic',
                'alcatel',
                'lenovo',
                'iphone',
                'ipod',
                'blackberry',
                'meizu',
                'android',
                'netfront',
                'symbian',
                'ucweb',
                'windowsce',
                'palm',
                'operamini',
                'operamobi',
                'openwave',
                'nexusone',
                'cldc',
                'midp',
                'wap',
                'mobile'
                );
            // 从HTTP_USER_AGENT中查找手机浏览器的关键字
            if (preg_match("/(" . implode('|', $clientkeywords) . ")/i", strtolower($_SERVER['HTTP_USER_AGENT']))) {
                return true;
            }
        }
        // 协议法，因为有可能不准确，放到最后判断
        if (isset ($_SERVER['HTTP_ACCEPT'])) {
            // 如果只支持wml并且不支持html那一定是移动设备
            // 如果支持wml和html但是wml在html之前则是移动设备
            if ((strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') !== false) && (strpos($_SERVER['HTTP_ACCEPT'], 'text/html') === false || (strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') < strpos($_SERVER['HTTP_ACCEPT'], 'text/html')))) {
                return true;
            }
        }

        return false;
    }
endif;

if(!function_exists('authcode')):
    // $string： 明文 或 密文
    // $operation：DECODE表示解密,其它表示加密
    // $key： 密匙
    // $expiry：密文有效期
    function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0)
    {
        // 动态密匙长度，相同的明文会生成不同密文就是依靠动态密匙
        $ckey_length = 4;

        // 密匙
        $key = md5($key ? $key : '34s7a!Edfas!&*(');

        // 密匙a会参与加解密
        $keya = md5(substr($key, 0, 16));
        // 密匙b会用来做数据完整性验证
        $keyb = md5(substr($key, 16, 16));
        // 密匙c用于变化生成的密文
        $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
        // 参与运算的密匙
        $cryptkey = $keya.md5($keya.$keyc);
        $key_length = strlen($cryptkey);
        // 明文，前10位用来保存时间戳，解密时验证数据有效性，10到26位用来保存$keyb(密匙b)，解密时会通过这个密匙验证数据完整性
        // 如果是解码的话，会从第$ckey_length位开始，因为密文前$ckey_length位保存 动态密匙，以保证解密正确
        $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
        $string_length = strlen($string);
        $result = '';
        $box = range(0, 255);
        $rndkey = array();
        // 产生密匙簿
        for ($i = 0; $i <= 255; $i++) {
            $rndkey[$i] = ord($cryptkey[$i % $key_length]);
        }
        // 用固定的算法，打乱密匙簿，增加随机性，好像很复杂，实际上对并不会增加密文的强度
        for ($j = $i = 0; $i < 256; $i++) {
            $j = ($j + $box[$i] + $rndkey[$i]) % 256;
            $tmp = $box[$i];
            $box[$i] = $box[$j];
            $box[$j] = $tmp;
        }
        // 核心加解密部分
        for ($a = $j = $i = 0; $i < $string_length; $i++) {
            $a = ($a + 1) % 256;
            $j = ($j + $box[$a]) % 256;
            $tmp = $box[$a];
            $box[$a] = $box[$j];
            $box[$j] = $tmp;
            // 从密匙簿得出密匙进行异或，再转成字符
            $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
        }
        if ($operation == 'DECODE') {
            // substr($result, 0, 10) == 0 验证数据有效性
            // substr($result, 0, 10) - time() > 0 验证数据有效性
            // substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16) 验证数据完整性
            // 验证数据有效性，请看未加密明文的格式
            if ((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
                return substr($result, 26);
            } else {
                return '';
            }
        } else {
            // 把动态密匙保存在密文里，这也是为什么同样的明文，生产不同密文后能解密的原因
            // 因为加密后的密文可能是一些特殊字符，复制过程可能会丢失，所以用base64编码
            return $keyc.str_replace('=', '', base64_encode($result));
        }
    }
endif;
