golang将IP地址片分类为字符串

时间:2018-01-22 20:16:52

标签: sorting go

我想在Golang中对一片IP地址(仅IPV4)进行排序。

使用sort的原始sort.Strings()软件包由于显而易见的原因无效,因为192.168.4.41

前面会自然排序192.168.4.5

通过在地图中对IP字符串旁边的IP值进行排序,我想出了一种方法来实现它,但感觉太手动了。这是分解IP字符串和排序地址的最有效方法吗?

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

package main

import (
  "fmt"
  "strconv"
  "strings"
  "sort"
)

func main() {
  ips := []string{
    "192.168.1.5",
    "69.52.220.44",
    "10.152.16.23",
    "192.168.3.10",
    "192.168.1.4",
    "192.168.1.41",
    }

ipsWithInt := make(map[string]int64)

for _, ip := range ips {
    ipStr := strings.Split(ip, ".")

    oct0, _ := strconv.ParseInt(ipStr[0], 10, 64)
    ipInt0 := oct0 * 255 * 255 * 255

    oct1, _ := strconv.ParseInt(ipStr[1], 10, 64)
    ipInt1 := oct1 * 255 * 255

    oct2, _ := strconv.ParseInt(ipStr[2], 10, 64)
    ipInt2 := oct2 * 255

    oct3, _ := strconv.ParseInt(ipStr[3], 10, 64)
    ipInt3 := oct3

    ipInt := ipInt0 + ipInt1 + ipInt2 + ipInt3

    ipsWithInt[ip] = ipInt
  }


  type kv struct {
    Key   string
    Value int64
  }

  var ss []kv
  for k, v := range ipsWithInt {
    ss = append(ss, kv{k, v})
  }

  sort.Slice(ss, func(i, j int) bool {
    return ss[i].Value < ss[j].Value
  })


  for _, kv := range ss {
    fmt.Printf("%s\n", kv.Key)
  }
}

结果:

10.152.16.23
69.52.220.44
192.168.1.4
192.168.1.5
192.168.1.41
192.168.3.10

1 个答案:

答案 0 :(得分:8)

有很多可能的方法可以做到这一点,但最容易想到的是将它们解析为net.IP s(只是字节切片,更准确的IP表示),以及然后排序:

realIPs := make([]net.IP, 0, len(ips))

for _, ip := range ips {
    realIPs = append(realIPs, net.ParseIP(ip))
}

sort.Slice(realIPs, func(i, j int) bool {
    return bytes.Compare(realIPs[i], realIPs[j]) < 0
})

这里的工作示例:https://play.golang.org/p/UtuvVz44_c8

这具有额外的优势,即无需修改即可与IPv6地址同样良好地工作。