处理IPv6的一些方法

<?php

/******************************************************
 * IPv6格式与长整型互相转换函数群
 *
 * @author 	Kevin<sky3hao@qq.com>
 * @create	2011-10-11 13:02:27
 * @version 	$ Revision: 1.5 $
 * @since   	PHP 5.1.0
 * @require 	PHP 4.2.0 (array_fill)
 *******************************************************/
function ip2long6($ipv6) { 
  	$ip_n = inet_pton($ipv6); 
  	$bits = 15; // 16 x 8 bit = 128bit 
  	while ($bits >= 0) { 
    	$bin = sprintf("%08b",(ord($ip_n[$bits]))); 
    	$ipv6long = $bin.$ipv6long; 
    	$bits--; 
  	} 
  	return gmp_strval(gmp_init($ipv6long,2),10); 
} 

function long2ip6($ipv6long) { 
  	$bin = gmp_strval(gmp_init($ipv6long,10),2); 
  	if (strlen($bin) < 128) { 
    	$pad = 128 - strlen($bin); 
    	for ($i = 1; $i <= $pad; $i++) { 
    	$bin = "0".$bin; 
    	} 
  	} 
  	$bits = 0; 
  	while ($bits <= 7) { 
   		$bin_part = substr($bin,($bits*16),16); 
    	$ipv6 .= dechex(bindec($bin_part)).":"; 
    	$bits++; 
  	} 
  	// compress 

  	return inet_ntop(inet_pton(substr($ipv6,0,-1))); 
} 

function php_compat_inet_pton($address) {
    $r = ip2long($address);
    if ($r !== false && $r != -1) {
        return pack('N', $r);
    }

    $delim_count = substr_count($address, ':');
    if ($delim_count < 1 || $delim_count > 7) {
        return false;
    }

    $r = explode(':', $address);
    $rcount = count($r);
    if (($doub = array_search('', $r, 1)) !== false) {
        $length = (!$doub || $doub == $rcount - 1 ? 2 : 1);
        array_splice($r, $doub, $length, array_fill(0, 8 + $length - $rcount, 0));
    }
    $r = array_map('hexdec', $r);
    array_unshift($r, 'n*');
    $r = call_user_func_array('pack', $r);
    return $r;
}

function php_compat_inet_ntop($in_addr){
    switch (strlen($in_addr)) {
        case 4:
            list(,$r) = unpack('N', $in_addr);
            return long2ip($r);
        case 16:
            $r = substr(chunk_split(bin2hex($in_addr), 4, ':'), 0, -1);
            $r = preg_replace(
                array('/(?::?\b0+\b:?){2,}/', '/\b0+([^0])/e'),
                array('::', '(int)"$1"?"$1":"0$1"'),
                $r);
            return $r;
    }
    return false;
}

if(!function_exists('inet_ntop')) {
    function inet_ntop($in_addr)
    {
        return php_compat_inet_ntop($in_addr);
    }
}

if (!function_exists('inet_pton')) {  
    function inet_pton($address) {
        return php_compat_inet_pton($address);
    }
}



/***************************************
 * 
 * 	IPv6 压缩格式和非压缩格式
 ***************************************/
function Compress($ip)	{
 	if (!strstr($ip, "::")) {
     	$ipPart = explode(":", $ip);
     	$ipComp = "";
     	$flag   = true;
     	for ($i = 0; $i < count($ipPart); $i++) {
         	if (!$ipPart[$i] and !$ipPart[$i+1]) {
             	break;
         	} else {
             	$ipComp = $ipComp.$ipPart[$i].":";
         	}
     	}
     	$ipComp = substr($ipComp, 0, -1);			
     	for (; $i < count($ipPart); $i++) {
         	if($flag) {
             	$flag   = !$flag;
             	$ipComp = $ipComp."::";
         	}
         	if(0 != $ipPart[$i]) {
             	break;
         	}
     	}

     	for (; $i < count($ipPart); $i++) {
         	$ipComp = $ipComp.$ipPart[$i].":";
     	}
 	}
 	if ('::' == substr($ipCom, strlen($ipcom)-2 )) {
     	$ip = substr($ipComp, 0, -1);
 	} else {
     	$ip = $ipComp ;			
 	}
 	
 	return $ip;		
}

function Uncompress($ip) {
 	if(strstr($ip, '::') ) {
     	$ipComp = str_replace('::', ':', $ip);
     	if(':' == $ipComp{0}) {
         	$ipComp = substr($ipComp, 1);
       	}

     	$ipParts = count(explode(':', $ipComp));
     	if (strstr($ip, '.')) {
         	$ipParts++;
    	}

     	$ipMiss = "" ;
     	for ($i = 0; (8-$ipParts) > $i; $i++) {
         	$ipMiss = $ipMiss.'0:';
     	}
     	if (0 != strpos($ip, '::') ) {
     		if (empty($ipMiss)) $ipMiss = "0:";
        	$ipMiss = ':'.$ipMiss;
        	$mid = strlen($ip) - strpos($ip, '::') - 2;
        	if (!$mid) $ipMiss .= "0";
     	}

     	$ip = str_replace('::', $ipMiss, $ip);
	}

 	return $ip;		
}

/***************************************
 * 
 * 	验证IPv6格式 
 ***************************************/
function validateIPv6($IP) { 
    return preg_match('/\A 
        (?: 
            (?: 
                    (?:[a-f0-9]{1,4}:){6} 
                | 
                    ::(?:[a-f0-9]{1,4}:){5} 
                | 
                    (?:[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){4} 
                | 
                    (?:(?:[a-f0-9]{1,4}:){0,1}[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){3} 
                | 
                    (?:(?:[a-f0-9]{1,4}:){0,2}[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){2} 
                | 
                    (?:(?:[a-f0-9]{1,4}:){0,3}[a-f0-9]{1,4})?::[a-f0-9]{1,4}: 
                | 
                    (?:(?:[a-f0-9]{1,4}:){0,4}[a-f0-9]{1,4})?:: 
            ) 
                (?: 
                        [a-f0-9]{1,4}:[a-f0-9]{1,4} 
                    | 
                        (?:(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3} 
                            (?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]) 
                ) 
            | 
                (?: 
                        (?:(?:[a-f0-9]{1,4}:){0,5}[a-f0-9]{1,4})?::[a-f0-9]{1,4} 
                    | 
                        (?:(?:[a-f0-9]{1,4}:){0,6}[a-f0-9]{1,4})?:: 
                ) 
        )\Z/ix', 
        $IP 
    ); 
} 

/*********************************************
 * 类似ip2long()的处理IPv6的方法
 * @param $Ip
 * @param $DatabaseParts
 *********************************************/
function IPv6ToLong($Ip, $DatabaseParts= 2) {
    $Ip = ExpandIPv6Notation($Ip);
    $Parts = explode(':', $Ip);
    $Ip = array('', '');
    for ($i = 0; $i < 4; $i++) $Ip[0] .= str_pad(base_convert($Parts[$i], 16, 2), 16, 0, STR_PAD_LEFT);
    for ($i = 4; $i < 8; $i++) $Ip[1] .= str_pad(base_convert($Parts[$i], 16, 2), 16, 0, STR_PAD_LEFT);

    if ($DatabaseParts == 2)
            return array(base_convert($Ip[0], 2, 10), base_convert($Ip[1], 2, 10));
    else    return base_convert($Ip[0], 2, 10) + base_convert($Ip[1], 2, 10);
}

function ExpandIPv6Notation($Ip) {
    if (strpos($Ip, '::') !== false)
        $Ip = str_replace('::', str_repeat(':0', 8 - substr_count($Ip, ':')).':', $Ip);
    if (strpos($Ip, ':') === 0) $Ip = '0'.$Ip;
    return $Ip;
}


?>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值