ip.go 3.4 KB

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