【问题标题】:How to detect if two Golang net.IPNet objects intersect?如何检测两个 Golang net.IPNet 对象是否相交?
【发布时间】:2016-04-16 05:05:14
【问题描述】:

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

也就是说,如果第一个网络是第二个网络的子网,如果第二个网络是第一个网络的子网,如何检查both

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上运行它

【问题讨论】:

    标签: networking go ip ip-address cidr


    【解决方案1】:

    如果(正如您的测试用例所暗示的那样)您不关心哪一边包含哪一边,而只是存在重叠,这应该就足够了。

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

    【讨论】:

    • 怎么样?很确定 IP 中的最终值将永远相同...您需要比较子网掩码或 IP 的子字符串。
    • @evanmcdonnal 我不确定你的意思。 IPNet.IP 是网络号,不是解析的 IP,我们只需要遏制。
    • 在这种情况下应该可以正常工作。我想我需要阅读文档。
    【解决方案2】:

    您可以使用 IP 地址 (net.IP) 和网络掩码 (net.IPMask) 只是包含二进制 IP 地址的字节切片 ([]byte) 这一事实。您可以对网络地址及其掩码使用通常的位运算符来确定一个网络是否是另一个网络的子网:

    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 的子网(反之亦然)。

    https://play.golang.org/p/Kur5n2hfLg

    【讨论】:

    • "它在您问题的所有测试用例中都成功,除了第一个。但毕竟,1.1.0.2/16 并不是 1.1.1.1/24 的子网(它是相反的)。”谢谢。但是,我真的需要检测任何交叉点,如果 n1 是 n2 的子网,或者 n2 是 n1 的子网。我会更新问题以明确这一点。
    猜你喜欢
    • 2018-12-17
    • 1970-01-01
    • 1970-01-01
    • 2012-06-23
    • 2016-06-27
    • 1970-01-01
    • 1970-01-01
    • 2011-04-19
    相关资源
    最近更新 更多