我有一个带有CIDR前缀的IPv6地址。 Ex: 2001:0:3238:DFE1:0063::FEFB/32
我希望编写一个函数,以便转换IPv6地址以匹配提供的CIDR前缀中的位数。这意味着,如果提供了前缀32,则IP地址应该从左边开始有32位,其余的应该是零。在上面的示例中,所需的输出应为:
2001:0000:0000:0000:0000:0000:0000:0000/32
我还有其他功能可以快捷方式缩短所需的IP,例如2001::/32
CIDR前缀的范围为0-128。
到目前为止,基于此帖子here,这是我所拥有的,但我不确定它是否提供了所需的输出。有人可以看一下并帮忙吗?我在这里直接考虑CIDR表示吗?
public function getCIDRMatchedIP( $ipAddress )
{
// Split in address and prefix length
list($firstaddrstr, $prefixlen) = explode('/', $ipAddress);
// Parse the address into a binary string
$firstaddrbin = inet_pton($firstaddrstr);
// Convert the binary string to a string with hexadecimal characters
# unpack() can be replaced with bin2hex()
# unpack() is used for symmetry with pack() below
$firstaddrhex = reset(unpack('H*', $firstaddrbin));
// Overwriting first address string to make sure notation is optimal
$firstaddrstr = inet_ntop($firstaddrbin);
$cidrMatchedString = $firstaddrstr.'/'.$prefixlen;
echo $cidrMatchedString;
}
答案 0 :(得分:1)
这里:
function getCIDRMatchedIP($ip)
{
if (strpos($ip, "::") !== false) {
$parts = explode(":", $ip);
$cnt = 0;
// Count number of parts with a number in it
for ($i = 0; $i < count($parts); $i++) {
if (is_numeric("0x" . $parts[$i]))
$cnt++;
}
// This is how many 0000 blocks is needed
$needed = 8 - $cnt;
$ip = str_replace("::", str_repeat(":0000", $needed), $ip);
}
list($ip, $prefix_len) = explode('/', $ip);
$parts = explode(":", $ip);
// This is the start bit mask
$bstring = str_repeat("1", $prefix_len) . str_repeat("0", 128 - $prefix_len);
$mins = str_split($bstring, 16);
$start = array();
for ($i = 0; $i < 8; $i++) {
$min = base_convert($mins[$i], 2, 16);
$start[] = sprintf("%04s", dechex(hexdec($parts[$i]) & hexdec($min)));
}
$start = implode(':', $start);
return $start . '/' . $prefix_len;
}
你调用函数getCIDRMatchedIP
:
echo getCIDRMatchedIP('2001:0:3238:DFE1:0063::FEFB/32');