英文:
net.IPNet inside other net.IPNet?
问题
在net.IPNet
类型中,我们有Contains
方法来检查一个net.IP
是否在其中。但是我想知道的是一个net.IPNet
是否在另一个net.IPNet
中。我尝试了使用big.Int
的解决方案,但它没有起作用(而且函数接口很糟糕)。有什么想法吗?
// ipnet2是否包含ipnet1?
func ContainsCIDR(ipnet1, ipnet2 net.IPNet) bool {
var begin big.Int
begin.SetBytes([]byte(ipnet1.IP))
var mask big.Int
mask.SetBytes([]byte(ipnet1.Mask))
var diff big.Int
diff.Xor(&begin, &mask)
var end big.Int
end.Add(&begin, &diff)
ipBegin := net.IP(begin.Bytes())
ipEnd := net.IP(end.Bytes())
return ipnet2.Contains(ipBegin) && ipnet2.Contains(ipEnd)
}
以上是给出的代码,用于判断一个net.IPNet
是否包含在另一个net.IPNet
中。
英文:
In net.IPNet
type we have the Contains method to check if a net.IP
is inside it. But what I want is to know if a net.IPNet
is inside another net.IPNet
. I tried a solution working with big.Int
but it didn't work (also, the function interface was terrible). Any ideas?
// ipnet2 contains ipnet1 ?
func ContainsCIDR(ipnet1, ipnet2 net.IPNet) bool {
var begin big.Int
begin.SetBytes([]byte(ipnet1.IP))
var mask big.Int
mask.SetBytes([]byte(ipnet1.Mask))
var diff big.Int
diff.Xor(&begin, &mask)
var end big.Int
end.Add(&begin, &diff)
ipBegin := net.IP(begin.Bytes())
ipEnd := net.IP(end.Bytes())
return ipnet2.Contains(ipBegin) && ipnet2.Contains(ipEnd)
}
答案1
得分: 3
检查外部子网的掩码是否与内部子网的大小相同或更小,然后验证内部子网的起始地址是否包含在外部子网中:
func ContainsCIDR(ipnet1, ipnet2 *net.IPNet) bool {
ones1, _ := ipnet1.Mask.Size()
ones2, _ := ipnet2.Mask.Size()
return ones1 <= ones2 && ipnet1.Contains(ipnet2.IP)
}
请注意,这是一个用Go语言编写的函数,用于检查两个CIDR(无类别域间路由)地址是否满足上述条件。
英文:
Check that the mask for the outer subnet is the same size or smaller than the inner, then verify that the starting address for the inner subnet is contained in the outer:
func ContainsCIDR(ipnet1, ipnet2 *net.IPNet) bool {
ones1, _ := ipnet1.Mask.Size()
ones2, _ := ipnet2.Mask.Size()
return ones1 <= ones2 && ipnet1.Contains(ipnet2.IP)
}
答案2
得分: 0
你可以使用IPAddress Go库来完成这个任务,使用以下代码。请注意,IPAddress可以处理其他类型的子网,不仅仅是CIDR子网。相同的代码也适用于单个地址。免责声明:我是项目经理。
func testContains(containing, contained string) {
containsIPAddress(containing, contained)
containsNet(containing, contained)
fmt.Println()
}
func containsIPAddress(containing, contained string) {
containingAddr, containedAddr := ipaddr.NewIPAddressString(containing),
ipaddr.NewIPAddressString(contained)
fmt.Printf("ipaddress: %s contains %s %v\n", containingAddr, containedAddr,
containingAddr.Contains(containedAddr))
}
func containsNet(containing, contained string) {
_, ipNetContaining, err := net.ParseCIDR(containing)
var ipNetContained *net.IPNet
if err == nil {
_, ipNetContained, err = net.ParseCIDR(contained)
}
if err != nil {
fmt.Printf("net: %s not a CIDR subnet\n", contained)
return
}
containingAddr, _ := ipaddr.NewIPAddressFromNetIPNet(ipNetContaining)
containedAddr, _ := ipaddr.NewIPAddressFromNetIPNet(ipNetContained)
fmt.Printf("net: %s contains %s %v\n", containingAddr, containedAddr,
containingAddr.Contains(containedAddr))
}
运行一些测试用例:
package main
import (
"fmt"
"github.com/seancfoley/ipaddress-go/ipaddr"
"net"
)
func main() {
testContains("172.17.0.0/16", "172.17.192.0/18")
testContains("172.17.0.0/16", "172.17.191.0/18")
testContains("10.10.20.0/30", "10.10.20.3/32")
testContains("10.10.20.0/30", "10.10.20.3")
testContains("10.10.20.0/30", "10.10.20.5")
testContains("10.10.20.0/30", "10.10.20.0/31")
testContains("10.10.20.0/30", "10.10.20.1-3")
testContains("1::/64", "2::/72")
testContains("1::/64", "1::/32")
testContains("1::/64", "1::/112")
testContains("1::3-4:5-6", "1::4:5-6")
testContains("1::3-4:5-6", "1::3-4:5")
testContains("1::3-4:5-6", "1::4:5-7")
testContains("1-2::/64", "2::/64")
testContains("bla", "foo")
}
输出结果:
ipaddress: 172.17.0.0/16 contains 172.17.192.0/18 true
net: 172.17.0.0/16 contains 172.17.192.0/18 true
ipaddress: 172.17.0.0/16 contains 172.17.191.0/18 true
net: 172.17.0.0/16 contains 172.17.128.0/18 true
ipaddress: 10.10.20.0/30 contains 10.10.20.3/32 true
net: 10.10.20.0/30 contains 10.10.20.3/32 true
ipaddress: 10.10.20.0/30 contains 10.10.20.3 true
net: 10.10.20.3 not a CIDR subnet
ipaddress: 10.10.20.0/30 contains 10.10.20.5 false
net: 10.10.20.5 not a CIDR subnet
ipaddress: 10.10.20.0/30 contains 10.10.20.0/31 true
net: 10.10.20.0/30 contains 10.10.20.0/31 true
ipaddress: 10.10.20.0/30 contains 10.10.20.1-3 true
net: 10.10.20.1-3 not a CIDR subnet
ipaddress: 1::/64 contains 2::/72 false
net: 1::/64 contains 2::/72 false
ipaddress: 1::/64 contains 1::/32 false
net: 1::/64 contains 1::/32 false
ipaddress: 1::/64 contains 1::/112 true
net: 1::/64 contains 1::/112 true
ipaddress: 1::3-4:5-6 contains 1::4:5-6 true
net: 1::4:5-6 not a CIDR subnet
ipaddress: 1::3-4:5-6 contains 1::3-4:5 true
net: 1::3-4:5 not a CIDR subnet
ipaddress: 1::3-4:5-6 contains 1::4:5-7 false
net: 1::4:5-7 not a CIDR subnet
ipaddress: 1-2::/64 contains 2::/64 true
net: 2::/64 not a CIDR subnet
ipaddress: bla contains foo false
net: foo not a CIDR subnet
英文:
You can do this with the IPAddress Go library using the following code. Note that IPAddress works with other types of subnets, not just CIDR subnets, as shown. The same code also works with individual addresses. Disclaimer: I am the project manager.
func testContains(containing, contained string) {
containsIPAddress(containing, contained)
containsNet(containing, contained)
fmt.Println()
}
func containsIPAddress(containing, contained string) {
containingAddr, containedAddr := ipaddr.NewIPAddressString(containing),
ipaddr.NewIPAddressString(contained)
fmt.Printf("ipaddress: %s contains %s %v\n", containingAddr, containedAddr,
containingAddr.Contains(containedAddr))
}
func containsNet(containing, contained string) {
_, ipNetContaining, err := net.ParseCIDR(containing)
var ipNetContained *net.IPNet
if err == nil {
_, ipNetContained, err = net.ParseCIDR(contained)
}
if err != nil {
fmt.Printf("net: %s not a CIDR subnet\n", contained)
return
}
containingAddr, _ := ipaddr.NewIPAddressFromNetIPNet(ipNetContaining)
containedAddr, _ := ipaddr.NewIPAddressFromNetIPNet(ipNetContained)
fmt.Printf("net: %s contains %s %v\n", containingAddr, containedAddr,
containingAddr.Contains(containedAddr))
}
Running some test cases:
package main
import (
"fmt"
"github.com/seancfoley/ipaddress-go/ipaddr"
"net"
)
func main() {
testContains("172.17.0.0/16", "172.17.192.0/18")
testContains("172.17.0.0/16", "172.17.191.0/18")
testContains("10.10.20.0/30", "10.10.20.3/32")
testContains("10.10.20.0/30", "10.10.20.3")
testContains("10.10.20.0/30", "10.10.20.5")
testContains("10.10.20.0/30", "10.10.20.0/31")
testContains("10.10.20.0/30", "10.10.20.1-3")
testContains("1::/64", "2::/72")
testContains("1::/64", "1::/32")
testContains("1::/64", "1::/112")
testContains("1::3-4:5-6", "1::4:5-6")
testContains("1::3-4:5-6", "1::3-4:5")
testContains("1::3-4:5-6", "1::4:5-7")
testContains("1-2::/64", "2::/64")
testContains("bla", "foo")
}
Output:
ipaddress: 172.17.0.0/16 contains 172.17.192.0/18 true
net: 172.17.0.0/16 contains 172.17.192.0/18 true
ipaddress: 172.17.0.0/16 contains 172.17.191.0/18 true
net: 172.17.0.0/16 contains 172.17.128.0/18 true
ipaddress: 10.10.20.0/30 contains 10.10.20.3/32 true
net: 10.10.20.0/30 contains 10.10.20.3/32 true
ipaddress: 10.10.20.0/30 contains 10.10.20.3 true
net: 10.10.20.3 not a CIDR subnet
ipaddress: 10.10.20.0/30 contains 10.10.20.5 false
net: 10.10.20.5 not a CIDR subnet
ipaddress: 10.10.20.0/30 contains 10.10.20.0/31 true
net: 10.10.20.0/30 contains 10.10.20.0/31 true
ipaddress: 10.10.20.0/30 contains 10.10.20.1-3 true
net: 10.10.20.1-3 not a CIDR subnet
ipaddress: 1::/64 contains 2::/72 false
net: 1::/64 contains 2::/72 false
ipaddress: 1::/64 contains 1::/32 false
net: 1::/64 contains 1::/32 false
ipaddress: 1::/64 contains 1::/112 true
net: 1::/64 contains 1::/112 true
ipaddress: 1::3-4:5-6 contains 1::4:5-6 true
net: 1::4:5-6 not a CIDR subnet
ipaddress: 1::3-4:5-6 contains 1::3-4:5 true
net: 1::3-4:5 not a CIDR subnet
ipaddress: 1::3-4:5-6 contains 1::4:5-7 false
net: 1::4:5-7 not a CIDR subnet
ipaddress: 1-2::/64 contains 2::/64 true
net: 2::/64 not a CIDR subnet
ipaddress: bla contains foo false
net: foo not a CIDR subnet
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论