calc.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. package cidr
  2. import (
  3. "bytes"
  4. "fmt"
  5. "math"
  6. "net"
  7. "sort"
  8. )
  9. // SuperNetting 合并网段
  10. func SuperNetting(ns []string) (*cidr, error) {
  11. num := len(ns)
  12. if num < 1 || (num&(num-1)) != 0 {
  13. return nil, fmt.Errorf("子网数量必须是2的次方")
  14. }
  15. mask := ""
  16. var cidrs []*cidr
  17. for _, n := range ns {
  18. // 检查子网CIDR有效性
  19. c, err := ParseCIDR(n)
  20. if err != nil {
  21. return nil, fmt.Errorf("网段%v格式错误", n)
  22. }
  23. cidrs = append(cidrs, c)
  24. // TODO 暂只考虑相同子网掩码的网段合并
  25. if len(mask) == 0 {
  26. mask = c.Mask()
  27. } else if c.Mask() != mask {
  28. return nil, fmt.Errorf("子网掩码不一致")
  29. }
  30. }
  31. AscSortCIDRs(cidrs)
  32. // 检查网段是否连续
  33. var network net.IP
  34. for _, c := range cidrs {
  35. if len(network) > 0 {
  36. if !network.Equal(c.ipNet.IP) {
  37. return nil, fmt.Errorf("必须是连续的网段")
  38. }
  39. }
  40. network = net.ParseIP(c.Broadcast())
  41. IncrIP(network)
  42. }
  43. // 子网掩码左移,得到共同的父网段
  44. c := cidrs[0]
  45. ones, bits := c.MaskSize()
  46. ones = ones - int(math.Log2(float64(num)))
  47. c.ipNet.Mask = net.CIDRMask(ones, bits)
  48. c.ipNet.IP.Mask(c.ipNet.Mask)
  49. return c, nil
  50. }
  51. // IncrIP IP地址自增
  52. func IncrIP(ip net.IP) {
  53. for i := len(ip) - 1; i >= 0; i-- {
  54. ip[i]++
  55. if ip[i] > 0 {
  56. break
  57. }
  58. }
  59. }
  60. // DecrIP IP地址自减
  61. func DecrIP(ip net.IP) {
  62. length := len(ip)
  63. for i := length - 1; i >= 0; i-- {
  64. ip[length-1]--
  65. if ip[length-1] < 0xFF {
  66. break
  67. }
  68. for j := 1; j < length; j++ {
  69. ip[length-j-1]--
  70. if ip[length-j-1] < 0xFF {
  71. return
  72. }
  73. }
  74. }
  75. }
  76. // Compare 比较IP大小 a等于b,返回0; a大于b,返回+1; a小于b,返回-1
  77. func Compare(a, b net.IP) int {
  78. return bytes.Compare(a, b)
  79. }
  80. // AscSortCIDRs 升序
  81. func AscSortCIDRs(cs []*cidr) {
  82. sort.Slice(cs, func(i, j int) bool {
  83. if n := bytes.Compare(cs[i].ipNet.IP, cs[j].ipNet.IP); n != 0 {
  84. return n < 0
  85. }
  86. if n := bytes.Compare(cs[i].ipNet.Mask, cs[j].ipNet.Mask); n != 0 {
  87. return n < 0
  88. }
  89. return false
  90. })
  91. }
  92. // DescSortCIDRs 降序
  93. func DescSortCIDRs(cs []*cidr) {
  94. sort.Slice(cs, func(i, j int) bool {
  95. if n := bytes.Compare(cs[i].ipNet.IP, cs[j].ipNet.IP); n != 0 {
  96. return n >= 0
  97. }
  98. if n := bytes.Compare(cs[i].ipNet.Mask, cs[j].ipNet.Mask); n != 0 {
  99. return n >= 0
  100. }
  101. return false
  102. })
  103. }