英文:
How to convert an ip's network segment in Golang?
问题
在golang中,你可以如何将"10.222.1.2/16"转换为"10.223.1.2/16"?可以将掩码视为相同。
例如:
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)
英文:
In golang, how can I convert 10.222.1.2/16 to 10.223.1.2/16?
Masks can be considered the same.
For example:
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"
==== Update 2023/05/09 ====
** @Volker: What have you tried so far? Where did you get stuck? **
I am very sorry that the previous description is not detailed enough. If the conversion is completed on paper, my thinking is as follows:
I tried how to implement this process through code, and I found a series of conversion methods that can convert ip to: []byte, uint32, etc.
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()
But I'm not quite sure what these things mean, and how to manipulate the data.
Thank you very much @Zeke Lu, I'm learning to understand this line of code, I use too few bit operators, and I'm not familiar with them:
v := ((v2 >> (32 - bits)) << (32 - bits)) | ((v1 << bits) >> bits)
答案1
得分: 0
也许这是你想要的:
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")
}
// 从v2的高位和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
}
// 解析前缀并将IPv4地址返回为uint32
func parse(prefix string) (uint32, int, error) {
p, err := netip.ParsePrefix(prefix)
if err != nil {
return 0, 0, err
}
// 只关注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"))
}
注意:这个代码没有完全测试过,请谨慎使用。
英文:
Maybe this is what you want:
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"))
}
Note: this is not fully tested. Use with caution.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论