rebuild ip and rm old file

This commit is contained in:
mz 2021-11-10 23:58:40 +08:00
parent 28d5d89e85
commit 48012f513a
7 changed files with 91 additions and 421 deletions

View File

@ -1,177 +0,0 @@
package main
import (
"CloudflareSpeedTest/task"
"bufio"
"log"
"net"
"os"
"strconv"
"strings"
)
// 根据子网掩码获取主机数量
func getCidrHostNum(maskLen int) int {
cidrIPNum := int(0)
if maskLen < 32 {
var i int = int(32 - maskLen - 1)
for ; i >= 1; i-- {
cidrIPNum += 1 << i
}
cidrIPNum += 2
} else {
cidrIPNum = 1
}
if cidrIPNum > 255 {
cidrIPNum = 255
}
return cidrIPNum
}
// 获取 IP 最后一段最小值和最大值
func getCidrIPRange(cidr string) (uint8, uint8) {
ip := strings.Split(cidr, "/")[0]
ipSegs := strings.Split(ip, ".")
maskLen, _ := strconv.Atoi(strings.Split(cidr, "/")[1])
seg4MinIP, seg4MaxIP := getIPSeg4Range(ipSegs, maskLen)
//ipPrefix := ipSegs[0] + "." + ipSegs[1] + "." + ipSegs[2] + "."
return seg4MinIP, seg4MaxIP
}
// 获取 IP 最后一段的区间
func getIPSeg4Range(ipSegs []string, maskLen int) (uint8, uint8) {
ipSeg, _ := strconv.Atoi(ipSegs[3])
return getIPSegRange(uint8(ipSeg), uint8(32-maskLen))
}
// 根据输入的基础IP地址和CIDR掩码计算一个IP片段的区间
func getIPSegRange(userSegIP, offset uint8) (uint8, uint8) {
var ipSegMax uint8 = 255
netSegIP := ipSegMax << offset
segMinIP := netSegIP & userSegIP
segMaxIP := userSegIP&(255<<offset) | ^(255 << offset)
return uint8(segMinIP), uint8(segMaxIP)
}
func loadFirstIPOfRangeFromFile(ipFile string) []net.IPAddr {
file, err := os.Open(ipFile)
if err != nil {
log.Fatal(err)
}
defer file.Close()
firstIPs := make([]net.IPAddr, 0)
scanner := bufio.NewScanner(file)
scanner.Split(bufio.ScanLines)
for scanner.Scan() {
IPString := scanner.Text()
if !strings.Contains(IPString, "/") { // 如果不含有 / 则代表不是 IP 段,而是一个单独的 IP因此需要加上 /32 /128 子网掩码
if task.IPv6 {
IPString += "/128"
} else {
IPString += "/32"
}
}
firstIP, IPRange, err := net.ParseCIDR(IPString)
//fmt.Println(firstIP)
//fmt.Println(IPRange)
if err != nil {
log.Fatal(err)
}
if !task.IPv6 { // IPv4
minIP, maxIP := getCidrIPRange(IPString) // 获取 IP 最后一段最小值和最大值
Mask, _ := strconv.Atoi(strings.Split(IPString, "/")[1]) // 获取子网掩码
MaxIPNum := getCidrHostNum(Mask) // 根据子网掩码获取主机数量
for IPRange.Contains(firstIP) {
if task.TestAll { // 如果是测速全部 IP
for i := minIP; i <= maxIP; i++ { // 遍历 IP 最后一段最小值到最大值
firstIP[15] = i
firstIPCopy := make([]byte, len(firstIP))
copy(firstIPCopy, firstIP)
firstIPs = append(firstIPs, net.IPAddr{IP: firstIPCopy})
}
} else { // 随机 IP 的最后一段 0.0.0.X
firstIP[15] = minIP + randipEndWith(MaxIPNum)
firstIPCopy := make([]byte, len(firstIP))
copy(firstIPCopy, firstIP)
firstIPs = append(firstIPs, net.IPAddr{IP: firstIPCopy})
}
firstIP[14]++ // 0.0.(X+1).X
if firstIP[14] == 0 {
firstIP[13]++ // 0.(X+1).X.X
if firstIP[13] == 0 {
firstIP[12]++ // (X+1).X.X.X
}
}
}
}
//IPv6
var tempIP uint8
for IPRange.Contains(firstIP) {
//fmt.Println(firstIP)
//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])
if !strings.Contains(IPString, "/128") {
firstIP[15] = randipEndWith(255) // 随机 IP 的最后一段
firstIP[14] = randipEndWith(255) // 随机 IP 的最后一段
}
firstIPCopy := make([]byte, len(firstIP))
copy(firstIPCopy, firstIP)
firstIPs = append(firstIPs, net.IPAddr{IP: firstIPCopy})
tempIP = firstIP[13]
firstIP[13] += randipEndWith(255)
if firstIP[13] < tempIP {
tempIP = firstIP[12]
firstIP[12] += randipEndWith(255)
if firstIP[12] < tempIP {
tempIP = firstIP[11]
firstIP[11] += randipEndWith(255)
if firstIP[11] < tempIP {
tempIP = firstIP[10]
firstIP[10] += randipEndWith(255)
if firstIP[10] < tempIP {
tempIP = firstIP[9]
firstIP[9] += randipEndWith(255)
if firstIP[9] < tempIP {
tempIP = firstIP[8]
firstIP[8] += randipEndWith(255)
if firstIP[8] < tempIP {
tempIP = firstIP[7]
firstIP[7] += randipEndWith(255)
if firstIP[7] < tempIP {
tempIP = firstIP[6]
firstIP[6] += randipEndWith(255)
if firstIP[6] < tempIP {
tempIP = firstIP[5]
firstIP[5] += randipEndWith(255)
if firstIP[5] < tempIP {
tempIP = firstIP[4]
firstIP[4] += randipEndWith(255)
if firstIP[4] < tempIP {
tempIP = firstIP[3]
firstIP[3] += randipEndWith(255)
if firstIP[3] < tempIP {
tempIP = firstIP[2]
firstIP[2] += randipEndWith(255)
if firstIP[2] < tempIP {
tempIP = firstIP[1]
firstIP[1] += randipEndWith(255)
if firstIP[1] < tempIP {
tempIP = firstIP[0]
firstIP[0] += randipEndWith(255)
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
return firstIPs
}

View File

@ -67,7 +67,7 @@ https://github.com/XIU2/CloudflareSpeedTest
flag.DurationVar(&utils.InputMaxDelay, "tl", 9999*time.Millisecond, "平均延迟上限")
flag.DurationVar(&utils.InputMinDelay, "tll", time.Duration(0), "平均延迟下限")
flag.DurationVar(&task.Timeout, "dt", 10*time.Second, "下载测速时间")
flag.IntVar(&task.TestCount, "dn", 20, "下载测速数量")
flag.IntVar(&task.TestCount, "dn", 10, "下载测速数量")
flag.StringVar(&task.URL, "url", "https://cf.xiu2.xyz/Github/CloudflareSpeedTest.png", "下载测速地址")
flag.BoolVar(&task.Disable, "dd", false, "禁用下载测速")
flag.BoolVar(&task.IPv6, "ipv6", false, "启用IPv6")
@ -94,9 +94,7 @@ https://github.com/XIU2/CloudflareSpeedTest
}
func main() {
go checkUpdate() // 检查版本更新
ips := task.LoadIPRanges()
// ips := loadFirstIPOfRangeFromFile(task.IPFile) // 读入IP
go checkUpdate() // 检查版本更新
// 开始延迟测速
fmt.Printf("# XIU2/CloudflareSpeedTest %s \n", version)
@ -106,7 +104,7 @@ func main() {
}
fmt.Printf("开始延迟测速模式TCP %s端口%d ,平均延迟上限:%v平均延迟下限%v)\n", ipVersion, task.TCPPort, utils.InputMaxDelay, utils.InputMinDelay)
pingData := task.NewPing(ips).Run().FilterDelay()
pingData := task.NewPing().Run().FilterDelay()
speedData := task.TestDownloadSpeed(pingData)
utils.ExportCsv(speedData)
speedData.Print(task.IPv6)

View File

@ -18,8 +18,8 @@ const (
bufferSize = 1024
defaultURL = "https://cf.xiu2.xyz/Github/CloudflareSpeedTest.png"
defaultTimeout = 10 * time.Second
defaultDisableDownlaod = false
defaultTestNum = 20
defaultDisableDownload = false
defaultTestNum = 10
defaultMinSpeed float64 = 0.0
)
@ -29,7 +29,7 @@ var (
// download timeout
Timeout = defaultTimeout
// disable download
Disable = defaultDisableDownlaod
Disable = defaultDisableDownload
TestCount = defaultTestNum
MinSpeed = defaultMinSpeed

View File

@ -27,7 +27,7 @@ func randipEndWith(num int) uint8 {
return uint8(rand.Intn(num))
}
func LoadIPRanges() []*net.IPAddr {
func loadIPRanges() []*net.IPAddr {
if IPFile == "" {
IPFile = defaultInputFile
}
@ -38,64 +38,72 @@ func LoadIPRanges() []*net.IPAddr {
defer file.Close()
firstIPs := make([]*net.IPAddr, 0)
scanner := bufio.NewScanner(file)
// scanner.Split(bufio.ScanLines)
for scanner.Scan() {
IPString := scanner.Text()
ipString := scanner.Text()
// 如果不含有 '/' 则代表不是 IP 段,而是一个单独的 IP因此需要加上 /32 /128 子网掩码
if !strings.Contains(IPString, "/") {
if !strings.Contains(ipString, "/") {
mask := "/32"
if IPv6 {
IPString += "/128"
} else {
IPString += "/32"
mask = "/128"
}
}
firstIP, IPRange, err := net.ParseCIDR(IPString)
// fmt.Println(firstIP)
// fmt.Println(IPRange)
if err != nil {
log.Fatal(err)
ipString += mask
}
if IPv6 {
//IPv6
loadIPv6(IPString, IPRange, firstIP, firstIPs)
firstIPs = append(firstIPs, loadIPv6(ipString)...)
continue
}
// IPv4
minIP, maxIP, mask := getCidrIPRange(IPString) // 获取 IP 最后一段最小值和最大值
maxIPNum := getCidrHostNum(mask) // 根据子网掩码获取主机数量
for IPRange.Contains(firstIP) {
if TestAll { // 如果是测速全部 IP
for i := minIP; i <= maxIP; i++ { // 遍历 IP 最后一段最小值到最大值
firstIP[15] = i
firstIPCopy := make([]byte, len(firstIP))
copy(firstIPCopy, firstIP)
firstIPs = append(firstIPs, &net.IPAddr{IP: firstIPCopy})
}
} else { // 随机 IP 的最后一段 0.0.0.X
firstIP[15] = minIP + randipEndWith(maxIPNum)
firstIPCopy := make([]byte, len(firstIP))
copy(firstIPCopy, firstIP)
firstIPs = append(firstIPs, &net.IPAddr{IP: firstIPCopy})
}
firstIP[14]++ // 0.0.(X+1).X
if firstIP[14] == 0 {
firstIP[13]++ // 0.(X+1).X.X
if firstIP[13] == 0 {
firstIP[12]++ // (X+1).X.X.X
}
}
}
firstIPs = append(firstIPs, loadIPv4(ipString)...)
}
return firstIPs
}
func loadIPv6(IPString string, IPRange *net.IPNet, firstIP net.IP, firstIPs []*net.IPAddr) {
func loadIPv4(ipString string) (firstIPs []*net.IPAddr) {
firstIP, IPRange, err := net.ParseCIDR(ipString)
// fmt.Println(firstIP)
// fmt.Println(IPRange)
if err != nil {
log.Fatal(err)
}
minIP, maxIP, hostNum := getCidrIPRange(ipString) // 获取 IP 最后一段最小值和最大值
for IPRange.Contains(firstIP) {
if TestAll { // 如果是测速全部 IP
for i := minIP; i <= maxIP; i++ { // 遍历 IP 最后一段最小值到最大值
firstIP[15] = i
firstIPCopy := make([]byte, len(firstIP))
copy(firstIPCopy, firstIP)
firstIPs = append(firstIPs, &net.IPAddr{IP: firstIPCopy})
}
} else { // 随机 IP 的最后一段 0.0.0.X
firstIP[15] = minIP + randipEndWith(hostNum)
firstIPCopy := make([]byte, len(firstIP))
copy(firstIPCopy, firstIP)
firstIPs = append(firstIPs, &net.IPAddr{IP: firstIPCopy})
}
firstIP[14]++ // 0.0.(X+1).X
if firstIP[14] == 0 {
firstIP[13]++ // 0.(X+1).X.X
if firstIP[13] == 0 {
firstIP[12]++ // (X+1).X.X.X
}
}
}
return
}
func loadIPv6(ipString string) (firstIPs []*net.IPAddr) {
firstIP, IPRange, err := net.ParseCIDR(ipString)
// fmt.Println(firstIP)
// fmt.Println(IPRange)
if err != nil {
log.Fatal(err)
}
var tempIP uint8
for IPRange.Contains(firstIP) {
//fmt.Println(firstIP)
//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])
if !strings.Contains(IPString, "/128") {
if !strings.Contains(ipString, "/128") {
firstIP[15] = randipEndWith(255) // 随机 IP 的最后一段
firstIP[14] = randipEndWith(255) // 随机 IP 的最后一段
}
@ -170,41 +178,44 @@ func loadIPv6(IPString string, IPRange *net.IPNet, firstIP net.IP, firstIPs []*n
tempIP = firstIP[0]
firstIP[0] += randipEndWith(255)
}
return
}
// 根据子网掩码获取主机数量
func getCidrHostNum(maskLen int) int {
cidrIPNum := int(0)
if maskLen < 32 {
var i int = int(32 - maskLen - 1)
for ; i >= 1; i-- {
cidrIPNum += 1 << i
func getCIDRHostNum(mask uint8) (subnetNum int) {
if mask >= 32 {
return 1
}
if mask < 32 {
for i := int(32 - mask - 1); i >= 1; i-- {
subnetNum += 1 << i
}
cidrIPNum += 2
} else {
cidrIPNum = 1
subnetNum += 2
}
if cidrIPNum > 255 {
cidrIPNum = 255
if subnetNum > 0xFF {
subnetNum = 0xFF
}
return cidrIPNum
return
}
// 获取 IP 最后一段最小值和最大值、子网掩码
func getCidrIPRange(cidr string) (minIP, maxIP uint8, mask int) {
ipRange := strings.Split(cidr, "/")
ipSegs := strings.Split(ipRange[0], ".")
mask, _ = strconv.Atoi(ipRange[1])
seg4, _ := strconv.Atoi(ipSegs[3])
// 获取 IP 最后一段最小值和最大值、主机数量
func getCidrIPRange(cidr string) (minIP, maxIP uint8, ipNum int) {
i := strings.IndexByte(cidr, '/')
addr := cidr[:i]
mask, _ := strconv.ParseUint(cidr[i+1:], 10, 8)
i = strings.LastIndexByte(addr, '.')
seg4, _ := strconv.ParseUint(addr[i+1:], 10, 8)
minIP, maxIP = getIPSegRange(uint8(seg4), uint8(32-mask))
ipNum = getCIDRHostNum(uint8(mask))
return
}
// 根据输入的基础IP地址和CIDR掩码计算一个IP片段的区间
func getIPSegRange(userSegIP, offset uint8) (uint8, uint8) {
var ipSegMax uint8 = 255
var ipSegMax uint8 = 0xFF
netSegIP := ipSegMax << offset
segMinIP := netSegIP & userSegIP
segMaxIP := userSegIP&(255<<offset) | ^(255 << offset)
segMaxIP := userSegIP&(0xFF<<offset) | ^(0xFF << offset)
return segMinIP, segMaxIP
}

View File

@ -45,8 +45,9 @@ func checkPingDefault() {
}
}
func NewPing(ips []*net.IPAddr) *Ping {
func NewPing() *Ping {
checkPingDefault()
ips := loadIPRanges()
return &Ping{
wg: &sync.WaitGroup{},
m: &sync.Mutex{},

164
util.go
View File

@ -1,164 +0,0 @@
package main
import (
"encoding/csv"
"log"
"math/rand"
"net"
"os"
"strconv"
"time"
"github.com/cheggaaa/pb/v3"
)
type CloudflareIPData struct {
ip net.IPAddr
pingCount int
pingReceived int
recvRate float32
downloadSpeed float32
pingTime time.Duration
}
func (cf *CloudflareIPData) getRecvRate() float32 {
if cf.recvRate == 0 {
pingLost := cf.pingCount - cf.pingReceived
cf.recvRate = float32(pingLost) / float32(cf.pingCount)
}
return cf.recvRate
}
func ExportCsv(filePath string, data []CloudflareIPData) {
fp, err := os.Create(filePath)
if err != nil {
log.Fatalf("创建文件[%s]失败:%v", filePath, err)
return
}
defer fp.Close()
w := csv.NewWriter(fp) //创建一个新的写入文件流
w.Write([]string{"IP 地址", "已发送", "已接收", "丢包率", "平均延迟", "下载速度 (MB/s)"})
w.WriteAll(convertToString(data))
w.Flush()
}
func (cf *CloudflareIPData) toString() []string {
result := make([]string, 6)
result[0] = cf.ip.String()
result[1] = strconv.Itoa(cf.pingCount)
result[2] = strconv.Itoa(cf.pingReceived)
result[3] = strconv.FormatFloat(float64(cf.getRecvRate()), 'f', 2, 32)
result[4] = cf.pingTime.String()
result[5] = strconv.FormatFloat(float64(cf.downloadSpeed)/1024/1024, 'f', 2, 32)
return result
}
func convertToString(data []CloudflareIPData) [][]string {
result := make([][]string, 0)
for _, v := range data {
result = append(result, v.toString())
}
return result
}
var pingTime int
var pingRoutine int
type progressEvent int
const (
NoAvailableIPFound progressEvent = iota
AvailableIPFound
NormalPing
)
var url string
var downloadTestTime time.Duration
const downloadBufferSize = 1024
var downloadTestCount int
//const defaultTcpPort = 443
const tcpConnectTimeout = time.Second * 1
var failTime int
// 平均延迟排序(丢包另算)
type CloudflareIPDataSet []CloudflareIPData
// 下载速度排序
type CloudflareIPDataSetD []CloudflareIPData
func initRandSeed() {
rand.Seed(time.Now().UnixNano())
}
func randipEndWith(num int) uint8 {
return uint8(rand.Intn(num))
}
func GetRandomString() string {
str := "0123456789abcdef"
bytes := []byte(str)
result := []byte{}
r := rand.New(rand.NewSource(time.Now().UnixNano()))
for i := 0; i < 4; i++ {
result = append(result, bytes[r.Intn(len(bytes))])
}
return string(result)
}
func ipPadding(ip string) string {
var ipLength int
var ipPrint string
ipPrint = ip
ipLength = len(ipPrint)
if ipLength < 15 {
for i := 0; i <= 15-ipLength; i++ {
ipPrint += " "
}
}
return ipPrint
}
func handleProgressGenerator(pb *pb.ProgressBar) func(e progressEvent) {
return func(e progressEvent) {
switch e {
case NoAvailableIPFound:
pb.Add(pingTime)
case AvailableIPFound:
pb.Add(failTime)
case NormalPing:
pb.Increment()
}
}
}
func (cfs CloudflareIPDataSet) Len() int {
return len(cfs)
}
func (cfs CloudflareIPDataSet) Less(i, j int) bool {
if (cfs)[i].getRecvRate() != cfs[j].getRecvRate() {
return cfs[i].getRecvRate() < cfs[j].getRecvRate()
}
return cfs[i].pingTime < cfs[j].pingTime
}
func (cfs CloudflareIPDataSet) Swap(i, j int) {
cfs[i], cfs[j] = cfs[j], cfs[i]
}
func (cfs CloudflareIPDataSetD) Len() int {
return len(cfs)
}
func (cfs CloudflareIPDataSetD) Less(i, j int) bool {
return cfs[i].downloadSpeed > cfs[j].downloadSpeed
}
func (cfs CloudflareIPDataSetD) Swap(i, j int) {
cfs[i], cfs[j] = cfs[j], cfs[i]
}

View File

@ -10,14 +10,15 @@ import (
"time"
)
const defaultOutput = "result.csv"
const (
defaultOutput = "result.csv"
maxDelay = 9999 * time.Millisecond
minDelay = time.Duration(0)
)
var (
MaxDelay = 9999 * time.Millisecond
MinDelay = time.Duration(0)
InputMaxDelay = MaxDelay
InputMinDelay = MinDelay
InputMaxDelay = maxDelay
InputMinDelay = minDelay
Output = defaultOutput
PrintNum = 20
)
@ -81,14 +82,14 @@ func convertToString(data []CloudflareIPData) [][]string {
type PingDelaySet []CloudflareIPData
func (s PingDelaySet) FilterDelay() (data PingDelaySet) {
if InputMaxDelay >= MaxDelay || InputMinDelay <= MinDelay {
if InputMaxDelay >= maxDelay || InputMinDelay <= minDelay {
return s
}
for _, v := range s {
if v.Delay > MaxDelay { // 平均延迟上限
if v.Delay > maxDelay { // 平均延迟上限
break
}
if v.Delay <= MinDelay { // 平均延迟下限
if v.Delay <= minDelay { // 平均延迟下限
continue
}
data = append(data, v) // 延迟满足条件时,添加到新数组中
@ -146,4 +147,4 @@ func (s DownloadSpeedSet) Print(ipv6 bool) {
for i := 0; i < PrintNum; i++ {
fmt.Printf(dataFormat, dateString[i][0], dateString[i][1], dateString[i][2], dateString[i][3], dateString[i][4], dateString[i][5])
}
}
}