如何检测两个Golang net.IPNet对象是否相交?

时间:2016-01-11 19:08:12

标签: networking go ip ip-address cidr

如何检测两个Golang net.IPNet对象之间是否存在交集?

也就是说,如果第一个网络是第二个网络 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

上运行它

2 个答案:

答案 0 :(得分:7)

如果(正如你的测试用例似乎暗示的那样)你不关心哪一方包含哪一方,而只是关注重叠,那就足够了。

func intersect(n1, n2 *net.IPNet) bool {
    return n2.Contains(n1.IP) || n1.Contains(n2.IP)
}

答案 1 :(得分:4)

您可以使用IP地址(net.IPMask)和netmasks([]byte)只是包含二进制IP地址的字节片(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 } )这一事实。您可以在网络地址及其掩码上使用通常的按位运算符来确定一个网络是否是另一个网络的子网:

1.1.0.2/16

此函数缺少一些基本的健全性检查(例如,当传递一个IPv4和一个IPv6地址时它会中断),但该示例应足以获得它的要点。

除了第一个问题之外,它在您的问题的所有测试用例中都取得了成功。但毕竟1.1.1.1/24并不是{{1}}的子网(反之亦然)。

  

Carton