【问题标题】:Go - check if IP address is in a networkGo - 检查 IP 地址是否在网络中
【发布时间】:2017-09-02 15:06:01
【问题描述】:

给定:

  • 网络地址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 的另一种方法:

【问题讨论】:

    标签: networking go ip-address subnet


    【解决方案1】:

    Go net package 包括以下功能:

    • ParseCIDR:接受一个表示 IP/掩码的字符串并返回一个 IP 和 IPNet
    • IPNet.Contains:检查一个IP是否在一个 网络

    这应该可以满足您的需求。

    【讨论】:

    • 谢谢,我会尝试使用它们
    【解决方案2】:

    根据 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")
        }
    
    }
    

    【讨论】:

      【解决方案3】:

      根据 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")
          }
      }
      

      【讨论】:

        【解决方案4】:

        根据上面的答案,人们可​​以轻松地将代码复制并粘贴到他们的项目中。

        package main
        
        import (
            "fmt"
            "log"
            "net"
        )
        
        func main() {
            // True
            firstCheck, err := cidrRangeContains("10.0.0.0/24", "10.0.0.1")
            if err != nil {
                log.Println(err)
            }
            fmt.Println(firstCheck)
            // False
            secondCheck, err := cidrRangeContains("10.0.0.0/24", "127.0.0.1")
            if err != nil {
                log.Println(err)
            }
            fmt.Println(secondCheck)
        
        }
        
        // Check if a certain ip in a cidr range.
        func cidrRangeContains(cidrRange string, checkIP string) (bool, error) {
            _, ipnet, err := net.ParseCIDR(cidrRange)
            if err != nil {
                return false, err
            }
            secondIP := net.ParseIP(checkIP)
            return ipnet.Contains(secondIP), err
        }
        

        【讨论】:

        • 忽略返回的错误是非常糟糕的做法。如果cidrRange 的格式不正确,您会感到恐慌(因为ipnet 将是nil)。
        • 我同意你的看法,我已经更新了代码,请随时更新代码。
        猜你喜欢
        • 2012-01-25
        • 2017-05-05
        • 2018-11-16
        • 2010-10-09
        • 2013-08-22
        • 1970-01-01
        • 1970-01-01
        • 2016-12-24
        • 1970-01-01
        相关资源
        最近更新 更多