如何在Golang中转换ip的网段?

2vuwiymt  于 2023-05-11  发布在  Go
关注(0)|答案(1)|浏览(160)

在golang中,如何将www.example.com转换为www.example.com掩码可以被认为是相同的。10.222.1.2/16 to 10.223.1.2/16? Masks can be considered the same.
例如:

func Netmap(ip string, dest string) string{}
Netmap("10.222.1.2/16", "10.223.0.0/16") // => "10.223.1.2/16"
Netmap("10.222.1.5/16", "10.224.0.0/16") // => "10.224.1.5/16"

====更新2023/05/09 ===

  • @Volker:到目前为止,你尝试了什么?你在哪里卡住了?*

非常抱歉,前面的描述不够详细。如果在纸上完成转换,我的想法如下:

我尝试了如何通过代码实现这个过程,我发现了一系列的转换方法,可以将ip转换为:[] byte、uint32等。

ip, ipNet, _ := net.ParseCIDR("10.222.1.2/16")
bytes := []byte(ip)
maskBits := binary.BigEndian.Uint32(ipNet.Mask)
ipBits := binary.BigEndian.Uint32(ip.To4())

prefix, _ := netip.ParsePrefix("10.222.1.2/16")
binary, _ := prefix.Addr().MarshalBinary()

但我不太确定这些东西意味着什么,以及如何操纵数据。
非常感谢@Zeke Lu,我正在学习理解这行代码,我使用的位运算符太少了,我对它们并不熟悉:

v := ((v2 >> (32 - bits)) << (32 - bits)) | ((v1 << bits) >> bits)
6tqwzwtp

6tqwzwtp1#

也许这就是你想要的:

package main

import (
    "encoding/binary"
    "errors"
    "fmt"
    "net/netip"
)

func Netmap(ip string, dest string) (string, error) {
    v1, bits, err := parse(ip)
    if err != nil {
        return "", err
    }

    v2, bits2, err := parse(dest)
    if err != nil {
        return "", err
    }

    if bits2 != bits {
        return "", errors.New("bits not matched")
    }

    // Construct from the high bits from v2 and the low bits from v1.
    v := ((v2 >> (32 - bits)) << (32 - bits)) | ((v1 << bits) >> bits)

    a4 := [4]byte{}
    binary.BigEndian.PutUint32(a4[:], v)
    addr := netip.AddrFrom4(a4)

    p := netip.PrefixFrom(addr, bits)

    return p.String(), nil
}

// parse parses the prefix and returns the IPv4 address as uint32.
func parse(prefix string) (uint32, int, error) {
    p, err := netip.ParsePrefix(prefix)
    if err != nil {
        return 0, 0, err
    }

    // Let's focus on IPv4.
    if !p.Addr().Is4() {
        return 0, 0, errors.New("unsupported IP version")
    }

    a4 := p.Addr().As4()
    v := binary.BigEndian.Uint32(a4[:])

    return v, p.Bits(), nil
}

func main() {
    fmt.Println(Netmap("10.222.1.2/16", "10.223.0.0/16"))
    fmt.Println(Netmap("10.222.1.5/16", "10.224.0.0/16"))
}

:未完全测试。请谨慎使用。

相关问题