Golang - 检查IP地址是否在网络中

tgo*_*gos 3 networking ip-address subnet go

鉴于:

  • 网络地址A :( 172.17.0.0/16)
  • 和来自主机B的IP地址:( 172.17.0.2/16)

如果B在A中怎么说?

所有地址都是以下列形式的字符串变量:[IP address in dot-decimal notation]/[subnet mask].我应该尝试通过操纵字符串(初步想法)来做到这一点.有不同的路径吗?

以下是Python的相同问题:

Go的另一种方法:

Zoy*_*oyd 11

围棋净包包括以下功能:

这应该涵盖您的需求.


bla*_*een 11

去1.18

您可以使用新的包net/netipnetip.Addr该包定义了比旧类型有重大改进的类型:

与 net.IP 类型相比,该包的 Addr 类型占用更少的内存,不可变且可比较(支持 == 并作为映射键)。

您可以使用以下方法检查 IP 是否在网络内Prefix.Contains

Contains 报告网络 p 是否包含 ip。

IPv4 地址不会与 IPv6 前缀匹配。v6 映射的 IPv6 地址将与 IPv4 前缀不匹配。零值 IP 将不匹配任何前缀。如果 ip 具有 IPv6 区域,则 Contains 返回 false,因为 Prefixes 会去除区域。

一个例子:

package main

import (
    "fmt"
    "net/netip"
)

func main() {
    network, err := netip.ParsePrefix("172.17.0.0/16")
    if err != nil {
        panic(err)
    }

    ip, err := netip.ParseAddr("172.17.0.2")
    if err != nil {
        panic(err)
    }

    b := network.Contains(ip)
    fmt.Println(b) // true
}
Run Code Online (Sandbox Code Playgroud)

如果您要检查的 IP 也有子网掩码,如172.17.0.2/16您的示例所示,您可以ip, err := netip.ParsePrefix再次使用,然后获取地址并将ip.Addr()其传递给Contains

操场上的代码:https://go.dev/play/p/ikWRpPa1egI


对于那些对实现细节感兴趣的人,可以查看Brad Fitzpatrick(Go 团队前成员)的这篇博文。net/netip软件包是基于该工作的。


tgo*_*gos 7

根据Zoyd的反馈...

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

package main

import (
    "fmt"
    "net"
)

func main() {

    A := "172.17.0.0/16"
    B := "172.17.0.2/16"

    ipA,ipnetA,_ := net.ParseCIDR(A)
    ipB,ipnetB,_ := net.ParseCIDR(B)

    fmt.Println("Network address A: ", A)
    fmt.Println("IP address      B: ", B)
    fmt.Println("ipA              : ", ipA)
    fmt.Println("ipnetA           : ", ipnetA)
    fmt.Println("ipB              : ", ipB)
    fmt.Println("ipnetB           : ", ipnetB)


    fmt.Printf("\nDoes A (%s) contain: B (%s)?\n", ipnetA, ipB)

    if ipnetA.Contains(ipB) {
        fmt.Println("yes")
    } else {
        fmt.Println("no")
    }

}
Run Code Online (Sandbox Code Playgroud)


小智 6

基于 tgogos 的回答:

package main

import (
    "fmt"
    "net"
)

func main() {
    A := "172.17.0.0/16"
    B := "172.17.0.2"

    _, ipnetA, _ := net.ParseCIDR(A)
    ipB := net.ParseIP(B)

    fmt.Printf("\nDoes A (%s) contain: B (%s)?\n", ipnetA, ipB)

    if ipnetA.Contains(ipB) {
        fmt.Println("yes")
    } else {
        fmt.Println("no")
    }
}
Run Code Online (Sandbox Code Playgroud)