ip.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. package task
  2. import (
  3. "bufio"
  4. "log"
  5. "math/rand"
  6. "net"
  7. "os"
  8. "strconv"
  9. "strings"
  10. "time"
  11. )
  12. const defaultInputFile = "ip.txt"
  13. var (
  14. // IPv6 IP version is 6
  15. IPv6 = false
  16. // TestAll test all ip
  17. TestAll = false
  18. // IPFile is the filename of IP Rangs
  19. IPFile = defaultInputFile
  20. )
  21. func randipEndWith(num int) uint8 {
  22. rand.Seed(time.Now().UnixNano())
  23. return uint8(rand.Intn(num))
  24. }
  25. func LoadIPRanges() []*net.IPAddr {
  26. if IPFile == "" {
  27. IPFile = defaultInputFile
  28. }
  29. file, err := os.Open(IPFile)
  30. if err != nil {
  31. log.Fatal(err)
  32. }
  33. defer file.Close()
  34. firstIPs := make([]*net.IPAddr, 0)
  35. scanner := bufio.NewScanner(file)
  36. // scanner.Split(bufio.ScanLines)
  37. for scanner.Scan() {
  38. IPString := scanner.Text()
  39. // 如果不含有 '/' 则代表不是 IP 段,而是一个单独的 IP,因此需要加上 /32 /128 子网掩码
  40. if !strings.Contains(IPString, "/") {
  41. if IPv6 {
  42. IPString += "/128"
  43. } else {
  44. IPString += "/32"
  45. }
  46. }
  47. firstIP, IPRange, err := net.ParseCIDR(IPString)
  48. // fmt.Println(firstIP)
  49. // fmt.Println(IPRange)
  50. if err != nil {
  51. log.Fatal(err)
  52. }
  53. if IPv6 {
  54. //IPv6
  55. loadIPv6(IPString, IPRange, firstIP, firstIPs)
  56. continue
  57. }
  58. // IPv4
  59. minIP, maxIP, mask := getCidrIPRange(IPString) // 获取 IP 最后一段最小值和最大值
  60. maxIPNum := getCidrHostNum(mask) // 根据子网掩码获取主机数量
  61. for IPRange.Contains(firstIP) {
  62. if TestAll { // 如果是测速全部 IP
  63. for i := minIP; i <= maxIP; i++ { // 遍历 IP 最后一段最小值到最大值
  64. firstIP[15] = i
  65. firstIPCopy := make([]byte, len(firstIP))
  66. copy(firstIPCopy, firstIP)
  67. firstIPs = append(firstIPs, &net.IPAddr{IP: firstIPCopy})
  68. }
  69. } else { // 随机 IP 的最后一段 0.0.0.X
  70. firstIP[15] = minIP + randipEndWith(maxIPNum)
  71. firstIPCopy := make([]byte, len(firstIP))
  72. copy(firstIPCopy, firstIP)
  73. firstIPs = append(firstIPs, &net.IPAddr{IP: firstIPCopy})
  74. }
  75. firstIP[14]++ // 0.0.(X+1).X
  76. if firstIP[14] == 0 {
  77. firstIP[13]++ // 0.(X+1).X.X
  78. if firstIP[13] == 0 {
  79. firstIP[12]++ // (X+1).X.X.X
  80. }
  81. }
  82. }
  83. }
  84. return firstIPs
  85. }
  86. func loadIPv6(IPString string, IPRange *net.IPNet, firstIP net.IP, firstIPs []*net.IPAddr) {
  87. var tempIP uint8
  88. for IPRange.Contains(firstIP) {
  89. //fmt.Println(firstIP)
  90. //fmt.Println(firstIP[0], firstIP[1], firstIP[2], firstIP[3], firstIP[4], firstIP[5], firstIP[6], firstIP[7], firstIP[8], firstIP[9], firstIP[10], firstIP[11], firstIP[12], firstIP[13], firstIP[14], firstIP[15])
  91. if !strings.Contains(IPString, "/128") {
  92. firstIP[15] = randipEndWith(255) // 随机 IP 的最后一段
  93. firstIP[14] = randipEndWith(255) // 随机 IP 的最后一段
  94. }
  95. firstIPCopy := make([]byte, len(firstIP))
  96. copy(firstIPCopy, firstIP)
  97. firstIPs = append(firstIPs, &net.IPAddr{IP: firstIPCopy})
  98. tempIP = firstIP[13]
  99. firstIP[13] += randipEndWith(255)
  100. if firstIP[13] >= tempIP {
  101. continue
  102. }
  103. tempIP = firstIP[12]
  104. firstIP[12] += randipEndWith(255)
  105. if firstIP[12] >= tempIP {
  106. continue
  107. }
  108. tempIP = firstIP[11]
  109. firstIP[11] += randipEndWith(255)
  110. if firstIP[11] >= tempIP {
  111. continue
  112. }
  113. tempIP = firstIP[10]
  114. firstIP[10] += randipEndWith(255)
  115. if firstIP[10] >= tempIP {
  116. continue
  117. }
  118. tempIP = firstIP[9]
  119. firstIP[9] += randipEndWith(255)
  120. if firstIP[9] >= tempIP {
  121. continue
  122. }
  123. tempIP = firstIP[8]
  124. firstIP[8] += randipEndWith(255)
  125. if firstIP[8] >= tempIP {
  126. continue
  127. }
  128. tempIP = firstIP[7]
  129. firstIP[7] += randipEndWith(255)
  130. if firstIP[7] >= tempIP {
  131. continue
  132. }
  133. tempIP = firstIP[6]
  134. firstIP[6] += randipEndWith(255)
  135. if firstIP[6] >= tempIP {
  136. continue
  137. }
  138. tempIP = firstIP[5]
  139. firstIP[5] += randipEndWith(255)
  140. if firstIP[5] >= tempIP {
  141. continue
  142. }
  143. tempIP = firstIP[4]
  144. firstIP[4] += randipEndWith(255)
  145. if firstIP[4] >= tempIP {
  146. continue
  147. }
  148. tempIP = firstIP[3]
  149. firstIP[3] += randipEndWith(255)
  150. if firstIP[3] >= tempIP {
  151. continue
  152. }
  153. tempIP = firstIP[2]
  154. firstIP[2] += randipEndWith(255)
  155. if firstIP[2] >= tempIP {
  156. continue
  157. }
  158. tempIP = firstIP[1]
  159. firstIP[1] += randipEndWith(255)
  160. if firstIP[1] >= tempIP {
  161. continue
  162. }
  163. tempIP = firstIP[0]
  164. firstIP[0] += randipEndWith(255)
  165. }
  166. }
  167. // 根据子网掩码获取主机数量
  168. func getCidrHostNum(maskLen int) int {
  169. cidrIPNum := int(0)
  170. if maskLen < 32 {
  171. var i int = int(32 - maskLen - 1)
  172. for ; i >= 1; i-- {
  173. cidrIPNum += 1 << i
  174. }
  175. cidrIPNum += 2
  176. } else {
  177. cidrIPNum = 1
  178. }
  179. if cidrIPNum > 255 {
  180. cidrIPNum = 255
  181. }
  182. return cidrIPNum
  183. }
  184. // 获取 IP 最后一段最小值和最大值、子网掩码
  185. func getCidrIPRange(cidr string) (minIP, maxIP uint8, mask int) {
  186. ipRange := strings.Split(cidr, "/")
  187. ipSegs := strings.Split(ipRange[0], ".")
  188. mask, _ = strconv.Atoi(ipRange[1])
  189. seg4, _ := strconv.Atoi(ipSegs[3])
  190. minIP, maxIP = getIPSegRange(uint8(seg4), uint8(32-mask))
  191. return
  192. }
  193. // 根据输入的基础IP地址和CIDR掩码计算一个IP片段的区间
  194. func getIPSegRange(userSegIP, offset uint8) (uint8, uint8) {
  195. var ipSegMax uint8 = 255
  196. netSegIP := ipSegMax << offset
  197. segMinIP := netSegIP & userSegIP
  198. segMaxIP := userSegIP&(255<<offset) | ^(255 << offset)
  199. return segMinIP, segMaxIP
  200. }