【问题标题】:Calculate and Convert IPv6 Address based on CIDR Prefix基于 CIDR Prefix 计算和转换 IPv6 地址
【发布时间】:2015-03-16 19:20:20
【问题描述】:

我有一个带有 CIDR 前缀的 IPv6 地址。 Ex: 2001:0:3238:DFE1:0063::FEFB/32

我希望编写一个函数,以便转换 IPv6 地址以匹配所提供的 CIDR 前缀中的位数。这意味着,如果提供了 32 前缀,则 IP 地址应从左开始包含 32 位,其余应为零。在上面的例子中,期望的输出应该是:

2001:0000:0000:0000:0000:0000:0000:0000/32

我确实有其他功能可以像 2001::/32 那样快捷地访问所需的 IP

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;
    }

【问题讨论】:

    标签: php ipv6


    【解决方案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');
    

    【讨论】:

    • 没问题,检查更新的答案,我做了一些修改。
    猜你喜欢
    • 2016-09-29
    • 2014-09-04
    • 1970-01-01
    • 2017-08-23
    • 2021-06-29
    • 1970-01-01
    • 2013-08-20
    • 2021-05-22
    • 1970-01-01
    相关资源
    最近更新 更多