如何检测两个 Golang net.IPNet 对象是否相交?
How to detect if two Golang net.IPNet objects intersect?
如何检测两个 Golang net.IPNet 对象之间是否有交集?
也就是说,如果第一个网络是第二个网络的子网,如何检查 both OR 如果第二个网络是第一个。
Go 是否提供任何适用于此特定任务的实用函数?
查看下面的测试代码。
package main
import (
"fmt"
"net"
)
func main() {
_, net1, _ := net.ParseCIDR("1.1.1.1/24")
_, net2, _ := net.ParseCIDR("1.1.0.2/16")
_, net3, _ := net.ParseCIDR("1.1.1.3/25")
_, net4, _ := net.ParseCIDR("1.2.0.4/16")
test(net1, net2, true)
test(net2, net1, true)
test(net1, net3, true)
test(net3, net1, true)
test(net1, net4, false)
test(net4, net1, false)
}
func test(n1, n2 *net.IPNet, expect bool) {
result := intersect(n1, n2)
var label string
if result == expect {
label = "good"
} else {
label = "FAIL"
}
fmt.Printf("test intersect(%v,%v)=%v expected=%v => %s\n", n1, n2, result, expect, label)
}
func intersect(n1, n2 *net.IPNet) bool {
return false // FIXME WRITEME
}
运行 它在 Go Playground
如果(正如您的测试用例所暗示的那样)您不关心哪一侧包含哪一侧,而只是有重叠,这就足够了。
func intersect(n1, n2 *net.IPNet) bool {
return n2.Contains(n1.IP) || n1.Contains(n2.IP)
}
您可以利用 IP 地址 (net.IP
) 和网络掩码 (net.IPMask
) 只是包含二进制 IP 地址的字节片 ([]byte
) 这一事实。您可以在网络地址及其掩码上使用通常的 bitwise-operators 来确定一个网络是否是另一个网络的子网:
func intersect(n1, n2 *net.IPNet) bool {
for i := range n1.IP {
if n1.IP[i] & n1.Mask[i] != n2.IP[i] & n2.Mask[i] & n1.Mask[i] {
return false
}
}
return true
}
此函数缺少一些基本的健全性检查(例如,当传递一个 IPv4 和一个 IPv6 地址时它会中断),但该示例应该足以理解它的要点。
它在你问题的所有测试用例中都成功了,除了第一个。但毕竟 1.1.0.2/16
并不是真正的 1.1.1.1/24
的子网(恰恰相反)。
如何检测两个 Golang net.IPNet 对象之间是否有交集?
也就是说,如果第一个网络是第二个网络的子网,如何检查 both OR 如果第二个网络是第一个。
Go 是否提供任何适用于此特定任务的实用函数?
查看下面的测试代码。
package main
import (
"fmt"
"net"
)
func main() {
_, net1, _ := net.ParseCIDR("1.1.1.1/24")
_, net2, _ := net.ParseCIDR("1.1.0.2/16")
_, net3, _ := net.ParseCIDR("1.1.1.3/25")
_, net4, _ := net.ParseCIDR("1.2.0.4/16")
test(net1, net2, true)
test(net2, net1, true)
test(net1, net3, true)
test(net3, net1, true)
test(net1, net4, false)
test(net4, net1, false)
}
func test(n1, n2 *net.IPNet, expect bool) {
result := intersect(n1, n2)
var label string
if result == expect {
label = "good"
} else {
label = "FAIL"
}
fmt.Printf("test intersect(%v,%v)=%v expected=%v => %s\n", n1, n2, result, expect, label)
}
func intersect(n1, n2 *net.IPNet) bool {
return false // FIXME WRITEME
}
运行 它在 Go Playground
如果(正如您的测试用例所暗示的那样)您不关心哪一侧包含哪一侧,而只是有重叠,这就足够了。
func intersect(n1, n2 *net.IPNet) bool {
return n2.Contains(n1.IP) || n1.Contains(n2.IP)
}
您可以利用 IP 地址 (net.IP
) 和网络掩码 (net.IPMask
) 只是包含二进制 IP 地址的字节片 ([]byte
) 这一事实。您可以在网络地址及其掩码上使用通常的 bitwise-operators 来确定一个网络是否是另一个网络的子网:
func intersect(n1, n2 *net.IPNet) bool {
for i := range n1.IP {
if n1.IP[i] & n1.Mask[i] != n2.IP[i] & n2.Mask[i] & n1.Mask[i] {
return false
}
}
return true
}
此函数缺少一些基本的健全性检查(例如,当传递一个 IPv4 和一个 IPv6 地址时它会中断),但该示例应该足以理解它的要点。
它在你问题的所有测试用例中都成功了,除了第一个。但毕竟 1.1.0.2/16
并不是真正的 1.1.1.1/24
的子网(恰恰相反)。