ip.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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. // TestAll test all ip
  15. TestAll = false
  16. // IPFile is the filename of IP Rangs
  17. IPFile = defaultInputFile
  18. IPText string
  19. )
  20. func InitRandSeed() {
  21. rand.Seed(time.Now().UnixNano())
  22. }
  23. func isIPv4(ip string) bool {
  24. return strings.Contains(ip, ".")
  25. }
  26. func randIPEndWith(num byte) byte {
  27. if num == 0 { // 对于 /32 这种单独的 IP
  28. return byte(0)
  29. }
  30. return byte(rand.Intn(int(num)))
  31. }
  32. type IPRanges struct {
  33. ips []*net.IPAddr
  34. mask string
  35. firstIP net.IP
  36. ipNet *net.IPNet
  37. }
  38. func newIPRanges() *IPRanges {
  39. return &IPRanges{
  40. ips: make([]*net.IPAddr, 0),
  41. }
  42. }
  43. func (r *IPRanges) fixIP(ip string) string {
  44. // 如果不含有 '/' 则代表不是 IP 段,而是一个单独的 IP,因此需要加上 /32 /128 子网掩码
  45. if i := strings.IndexByte(ip, '/'); i < 0 {
  46. if isIPv4(ip) {
  47. r.mask = "/32"
  48. } else {
  49. r.mask = "/128"
  50. }
  51. ip += r.mask
  52. } else {
  53. r.mask = ip[i:]
  54. }
  55. return ip
  56. }
  57. func (r *IPRanges) parseCIDR(ip string) {
  58. var err error
  59. if r.firstIP, r.ipNet, err = net.ParseCIDR(r.fixIP(ip)); err != nil {
  60. log.Fatalln("ParseCIDR err", err)
  61. }
  62. }
  63. func (r *IPRanges) appendIPv4(d byte) {
  64. r.appendIP(net.IPv4(r.firstIP[12], r.firstIP[13], r.firstIP[14], d))
  65. }
  66. func (r *IPRanges) appendIP(ip net.IP) {
  67. r.ips = append(r.ips, &net.IPAddr{IP: ip})
  68. }
  69. // 返回第四段 ip 的最小值及可用数目
  70. func (r *IPRanges) getIPRange() (minIP, hosts byte) {
  71. minIP = r.firstIP[15] & r.ipNet.Mask[3] // IP 第四段最小值
  72. // 根据子网掩码获取主机数量
  73. m := net.IPv4Mask(255, 255, 255, 255)
  74. for i, v := range r.ipNet.Mask {
  75. m[i] ^= v
  76. }
  77. total, _ := strconv.ParseInt(m.String(), 16, 32) // 总可用 IP 数
  78. if total > 255 { // 矫正 第四段 可用 IP 数
  79. hosts = 255
  80. return
  81. }
  82. hosts = byte(total)
  83. return
  84. }
  85. func (r *IPRanges) chooseIPv4() {
  86. minIP, hosts := r.getIPRange()
  87. for r.ipNet.Contains(r.firstIP) {
  88. if TestAll { // 如果是测速全部 IP
  89. for i := 0; i <= int(hosts); i++ { // 遍历 IP 最后一段最小值到最大值
  90. r.appendIPv4(byte(i) + minIP)
  91. }
  92. } else { // 随机 IP 的最后一段 0.0.0.X
  93. r.appendIPv4(minIP + randIPEndWith(hosts))
  94. }
  95. r.firstIP[14]++ // 0.0.(X+1).X
  96. if r.firstIP[14] == 0 {
  97. r.firstIP[13]++ // 0.(X+1).X.X
  98. if r.firstIP[13] == 0 {
  99. r.firstIP[12]++ // (X+1).X.X.X
  100. }
  101. }
  102. }
  103. }
  104. func (r *IPRanges) chooseIPv6() {
  105. var tempIP uint8
  106. for r.ipNet.Contains(r.firstIP) {
  107. if r.mask != "/128" {
  108. r.firstIP[15] = randIPEndWith(255) // 随机 IP 的最后一段
  109. r.firstIP[14] = randIPEndWith(255) // 随机 IP 的最后一段
  110. }
  111. targetIP := make([]byte, len(r.firstIP))
  112. copy(targetIP, r.firstIP)
  113. r.appendIP(targetIP)
  114. for i := 13; i >= 0; i-- {
  115. tempIP = r.firstIP[i]
  116. r.firstIP[i] += randIPEndWith(255)
  117. if r.firstIP[i] >= tempIP {
  118. break
  119. }
  120. }
  121. }
  122. }
  123. func loadIPRanges() []*net.IPAddr {
  124. ranges := newIPRanges()
  125. if IPText != "" { // 从参数中获取 IP 段数据
  126. IPs := strings.Split(IPText, ",")
  127. for _, IP := range IPs {
  128. ranges.parseCIDR(IP)
  129. if isIPv4(IP) {
  130. ranges.chooseIPv4()
  131. } else {
  132. ranges.chooseIPv6()
  133. }
  134. }
  135. } else { // 从文件中获取 IP 段数据
  136. if IPFile == "" {
  137. IPFile = defaultInputFile
  138. }
  139. file, err := os.Open(IPFile)
  140. if err != nil {
  141. log.Fatal(err)
  142. }
  143. defer file.Close()
  144. scanner := bufio.NewScanner(file)
  145. for scanner.Scan() {
  146. ranges.parseCIDR(scanner.Text())
  147. if isIPv4(scanner.Text()) {
  148. ranges.chooseIPv4()
  149. } else {
  150. ranges.chooseIPv6()
  151. }
  152. }
  153. }
  154. return ranges.ips
  155. }