自動目錄
由於 IPv4 可以轉成十進位用推移的運算,但是 IPv6 要轉成十進位的話,會超過有效位數的顯示,另外由於ipv6本身是用十六進位表示,沒必要換成10進位。所以要用更漂亮的作法。我把他寫成 class = =!!:
函式
/**
* ipv6 class by axer@ms1.boe.tcc.edu.tw
*/
class ipv6{
/**
* ExpandIPv6Notation2Bin()- Convert an ipv6 address to bin string
* @param string $ip6 - an ipv6 address
* @return return the binary string of an ipv6 address if parameter ip6 is an ipv6 address,
* else it return an empty string.
*/
public function ExpandIPv6Notation2Bin($ip6) {
if (strpos($ip6, '::') !== false)
$ip6 = str_replace('::', str_repeat(':0', 8 - substr_count($ip6, ':')).':', $ip6);
$ip6parts = explode(':', $ip6);
$res="";
foreach ($ip6parts as $part)
$res .= str_pad(base_convert( $part, 16, 2), 16, 0, STR_PAD_LEFT);
return $res;
}
/**
* MatchCIDR6 -- Check if an ipv6 address is in the CDIR6 subnet.
* @param string $cidr6 - an ipv6 subnet, ex 2001:288:5400/39 or 2001:288:5432:/64 or 2001:288:5478::/64..
* @param string $chkipv6 - an ipv6 address, ex ::1, 2001:288:5200::1, :: ,etc.
* @return return true if $chkipv6 is inside the $cidr6 subnet, or return false.
*/
public function MatchCIDR6( $cidr6, $chkipv6)
{
list($ip6, $prefixlen) = explode('/', $cidr6);
$cidrbin= substr( $this->ExpandIPv6Notation2Bin($ip6), 0, $prefixlen);
$chkip6bin= substr( $this->ExpandIPv6Notation2Bin($chkipv6), 0, $prefixlen);
if(! strcmp($cidrbin,$chkip6bin))return true;
return false;
}
}
用法
$cidr6 = "2001:288:5400/39";
$ip6= "2001:288:5300:000::72A:4BE7";
$o_ipv6 = new ipv6();
// 檢查是ip6 是否在網段內
if( $o_ipv6->MatchCIDR6($cidr6,$ip6))
print "Inside";
else
print "Outside";
備註:有參考別人的程式,不過來源佚失了
相關連結
原文 2009-11-26