根据CIDR前缀计算和转换IPv6地址

时间:2015-03-16 19:20:20

标签: php ipv6

我有一个带有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;
    }

1 个答案:

答案 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');