util.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. package main
  2. import (
  3. "encoding/csv"
  4. "log"
  5. "math/rand"
  6. "net"
  7. "os"
  8. "strconv"
  9. "time"
  10. "github.com/cheggaaa/pb/v3"
  11. )
  12. type CloudflareIPData struct {
  13. ip net.IPAddr
  14. pingCount int
  15. pingReceived int
  16. recvRate float32
  17. downloadSpeed float32
  18. pingTime float32
  19. }
  20. func (cf *CloudflareIPData) getRecvRate() float32 {
  21. if cf.recvRate == 0 {
  22. pingLost := cf.pingCount - cf.pingReceived
  23. cf.recvRate = float32(pingLost) / float32(cf.pingCount)
  24. }
  25. return cf.recvRate
  26. }
  27. func ExportCsv(filePath string, data []CloudflareIPData) {
  28. fp, err := os.Create(filePath)
  29. if err != nil {
  30. log.Fatalf("创建文件["+filePath+"]句柄失败,%v", err)
  31. return
  32. }
  33. defer fp.Close()
  34. w := csv.NewWriter(fp) //创建一个新的写入文件流
  35. w.Write([]string{"IP 地址", "已发送", "已接收", "丢包率", "平均延迟", "下载速度 (MB/s)"})
  36. w.WriteAll(convertToString(data))
  37. w.Flush()
  38. }
  39. func (cf *CloudflareIPData) toString() []string {
  40. result := make([]string, 6)
  41. result[0] = cf.ip.String()
  42. result[1] = strconv.Itoa(cf.pingCount)
  43. result[2] = strconv.Itoa(cf.pingReceived)
  44. result[3] = strconv.FormatFloat(float64(cf.getRecvRate()), 'f', 2, 32)
  45. result[4] = strconv.FormatFloat(float64(cf.pingTime), 'f', 2, 32)
  46. result[5] = strconv.FormatFloat(float64(cf.downloadSpeed)/1024/1024, 'f', 2, 32)
  47. return result
  48. }
  49. func convertToString(data []CloudflareIPData) [][]string {
  50. result := make([][]string, 0)
  51. for _, v := range data {
  52. result = append(result, v.toString())
  53. }
  54. return result
  55. }
  56. var pingTime int
  57. var pingRoutine int
  58. type progressEvent int
  59. const (
  60. NoAvailableIPFound progressEvent = iota
  61. AvailableIPFound
  62. NormalPing
  63. )
  64. var url string
  65. var downloadTestTime time.Duration
  66. const downloadBufferSize = 1024
  67. var downloadTestCount int
  68. //const defaultTcpPort = 443
  69. const tcpConnectTimeout = time.Second * 1
  70. var failTime int
  71. // 平均延迟排序(丢包另算)
  72. type CloudflareIPDataSet []CloudflareIPData
  73. // 下载速度排序
  74. type CloudflareIPDataSetD []CloudflareIPData
  75. func initRandSeed() {
  76. rand.Seed(time.Now().UnixNano())
  77. }
  78. func randipEndWith(num int) uint8 {
  79. return uint8(rand.Intn(num))
  80. }
  81. func GetRandomString() string {
  82. str := "0123456789abcdef"
  83. bytes := []byte(str)
  84. result := []byte{}
  85. r := rand.New(rand.NewSource(time.Now().UnixNano()))
  86. for i := 0; i < 4; i++ {
  87. result = append(result, bytes[r.Intn(len(bytes))])
  88. }
  89. return string(result)
  90. }
  91. func ipPadding(ip string) string {
  92. var ipLength int
  93. var ipPrint string
  94. ipPrint = ip
  95. ipLength = len(ipPrint)
  96. if ipLength < 15 {
  97. for i := 0; i <= 15-ipLength; i++ {
  98. ipPrint += " "
  99. }
  100. }
  101. return ipPrint
  102. }
  103. func handleProgressGenerator(pb *pb.ProgressBar) func(e progressEvent) {
  104. return func(e progressEvent) {
  105. switch e {
  106. case NoAvailableIPFound:
  107. pb.Add(pingTime)
  108. case AvailableIPFound:
  109. pb.Add(failTime)
  110. case NormalPing:
  111. pb.Increment()
  112. }
  113. }
  114. }
  115. func (cfs CloudflareIPDataSet) Len() int {
  116. return len(cfs)
  117. }
  118. func (cfs CloudflareIPDataSet) Less(i, j int) bool {
  119. if (cfs)[i].getRecvRate() != cfs[j].getRecvRate() {
  120. return cfs[i].getRecvRate() < cfs[j].getRecvRate()
  121. }
  122. return cfs[i].pingTime < cfs[j].pingTime
  123. }
  124. func (cfs CloudflareIPDataSet) Swap(i, j int) {
  125. cfs[i], cfs[j] = cfs[j], cfs[i]
  126. }
  127. func (cfs CloudflareIPDataSetD) Len() int {
  128. return len(cfs)
  129. }
  130. func (cfs CloudflareIPDataSetD) Less(i, j int) bool {
  131. return cfs[i].downloadSpeed > cfs[j].downloadSpeed
  132. }
  133. func (cfs CloudflareIPDataSetD) Swap(i, j int) {
  134. cfs[i], cfs[j] = cfs[j], cfs[i]
  135. }