From 859251ab3f82cf6272373b1ec75093d403bd734f Mon Sep 17 00:00:00 2001 From: GuanM <1-GuanM@users.noreply.gitlab.54sxh.cn> Date: Wed, 19 Jun 2024 01:14:21 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AF=BC=E5=85=A5=E5=A4=96=E9=83=A8=E5=BA=93?= =?UTF-8?q?=E5=B9=B6=E6=B5=8B=E8=AF=95=E7=BD=91=E7=BB=9C=E6=88=90=E5=8A=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.go | 33 +++++++++---- task/Yinyong.go | 125 +++++++++++++++++++++++++++++++++++++++++++++++ task/download.go | 6 +++ 3 files changed, 155 insertions(+), 9 deletions(-) create mode 100644 task/Yinyong.go create mode 100644 task/download.go diff --git a/main.go b/main.go index 6eceeca..807ded1 100644 --- a/main.go +++ b/main.go @@ -9,16 +9,23 @@ import ( var ( VersionPrint bool Version string + DDownload bool ) func init() { // checkUpdate() // 定义一个字符串类型的命令行标志 - flag.IntVar(&task.TcpPort, "p", 443, "TCP端口") + flag.IntVar(&task.TcpPort, "tcp", 443, "TCP端口") flag.IntVar(&task.PingTimes, "t", 4, "Ping次数") - flag.IntVar(&task.Routines, "r", 200, "并发数") + flag.IntVar(&task.Routines, "r", 200, "存活检测并发数检测") + flag.IntVar(&task.MinMS, "mis", 0, "只输出高于指定平均延迟的 IP") + flag.IntVar(&task.MaxMS, "mxs", 1000, "只输出低于指定平均延迟的 IP") + flag.IntVar(&task.DownloadNum, "dn", 10, "下载数量") + flag.StringVar(&task.DownloadUrl, "url", "https://github.com", "默认文件下载地址") + flag.BoolVar(&task.TestAll, "ta", false, "测试所有 IP") + flag.BoolVar(&DDownload, "du", false, "禁止下载") flag.BoolVar(&VersionPrint, "v", false, "输出版本") - flag.BoolVar(&task.IsOff, "om", false, "是否为离线模式") + flag.BoolVar(&task.IsOff, "om", false, "不下载子网列表") flag.Parse() if VersionPrint { fmt.Println("Version:", Version) @@ -29,14 +36,22 @@ func main() { if VersionPrint { return } + // InitRandSeed 初始化随机数种子 + task.InitRandSeed() // 输出版本 fmt.Printf("# DockerST %s \n", Version) - _ = task.CreateData().Run() -} + pingData := task.CreateData().Run().ExcludeInvalid() + // 按照延迟排序 + sortedPingData := task.SortNodesDesc(pingData) + // 仅输出前10个结果 + for i, ipDelay := range sortedPingData { + if i >= 10 { + break + } + fmt.Printf("IP: %s, 延迟: %s\n", ipDelay.IP.String(), ipDelay.Delay) + } -func WriteHost(domain string, ip string) { + if DDownload { -} - -func checkUpdate() { + } } diff --git a/task/Yinyong.go b/task/Yinyong.go new file mode 100644 index 0000000..1013906 --- /dev/null +++ b/task/Yinyong.go @@ -0,0 +1,125 @@ +package task + +import ( + "log" + "net" + "strconv" + "strings" +) + +type IPRanges struct { + ips []*net.IPAddr + mask string + firstIP net.IP + ipNet *net.IPNet +} + +func newIPRanges() *IPRanges { + return &IPRanges{ + ips: make([]*net.IPAddr, 0), + } +} + +// 如果是单独 IP 则加上子网掩码,反之则获取子网掩码(r.mask) +func (r *IPRanges) fixIP(ip string) string { + // 如果不含有 '/' 则代表不是 IP 段,而是一个单独的 IP,因此需要加上 /32 /128 子网掩码 + if i := strings.IndexByte(ip, '/'); i < 0 { + if IsIpv4(ip) { + r.mask = "/32" + } else { + r.mask = "/128" + } + ip += r.mask + } else { + r.mask = ip[i:] + } + return ip +} + +// 解析 IP 段,获得 IP、IP 范围、子网掩码 +func (r *IPRanges) parseCIDR(ip string) { + var err error + if r.firstIP, r.ipNet, err = net.ParseCIDR(r.fixIP(ip)); err != nil { + log.Fatalln("ParseCIDR err", err) + } +} + +func (r *IPRanges) appendIPv4(d byte) { + r.appendIP(net.IPv4(r.firstIP[12], r.firstIP[13], r.firstIP[14], d)) +} + +func (r *IPRanges) appendIP(ip net.IP) { + r.ips = append(r.ips, &net.IPAddr{IP: ip}) +} + +// 返回第四段 ip 的最小值及可用数目 +func (r *IPRanges) getIPRange() (minIP, hosts byte) { + minIP = r.firstIP[15] & r.ipNet.Mask[3] // IP 第四段最小值 + + // 根据子网掩码获取主机数量 + m := net.IPv4Mask(255, 255, 255, 255) + for i, v := range r.ipNet.Mask { + m[i] ^= v + } + total, _ := strconv.ParseInt(m.String(), 16, 32) // 总可用 IP 数 + if total > 255 { // 矫正 第四段 可用 IP 数 + hosts = 255 + return + } + hosts = byte(total) + return +} + +func (r *IPRanges) chooseIPv4() { + if r.mask == "/32" { // 单个 IP 则无需随机,直接加入自身即可 + r.appendIP(r.firstIP) + } else { + minIP, hosts := r.getIPRange() // 返回第四段 IP 的最小值及可用数目 + for r.ipNet.Contains(r.firstIP) { // 只要该 IP 没有超出 IP 网段范围,就继续循环随机 + if TestAll { // 如果是测速全部 IP + for i := 0; i <= int(hosts); i++ { // 遍历 IP 最后一段最小值到最大值 + r.appendIPv4(byte(i) + minIP) + } + } else { // 随机 IP 的最后一段 0.0.0.X + r.appendIPv4(minIP + randIPEndWith(hosts)) + } + r.firstIP[14]++ // 0.0.(X+1).X + if r.firstIP[14] == 0 { + r.firstIP[13]++ // 0.(X+1).X.X + if r.firstIP[13] == 0 { + r.firstIP[12]++ // (X+1).X.X.X + } + } + } + } +} + +func (r *IPRanges) chooseIPv6() { + if r.mask == "/128" { // 单个 IP 则无需随机,直接加入自身即可 + r.appendIP(r.firstIP) + } else { + var tempIP uint8 // 临时变量,用于记录前一位的值 + for r.ipNet.Contains(r.firstIP) { // 只要该 IP 没有超出 IP 网段范围,就继续循环随机 + r.firstIP[15] = randIPEndWith(255) // 随机 IP 的最后一段 + r.firstIP[14] = randIPEndWith(255) // 随机 IP 的最后一段 + + targetIP := make([]byte, len(r.firstIP)) + _ = copy(targetIP, r.firstIP) + r.appendIP(targetIP) // 加入 IP 地址池 + + for i := 13; i >= 0; i-- { // 从倒数第三位开始往前随机 + tempIP = r.firstIP[i] // 保存前一位的值 + r.firstIP[i] += randIPEndWith(255) // 随机 0~255,加到当前位上 + if r.firstIP[i] >= tempIP { // 如果当前位的值大于等于前一位的值,说明随机成功了,可以退出该循环 + break + } + } + } + } +} +func randIPEndWith(num byte) byte { + if num == 0 { // 对于 /32 这种单独的 IP + return byte(0) + } + return byte(randGen.Intn(int(num))) +} diff --git a/task/download.go b/task/download.go new file mode 100644 index 0000000..ac44e06 --- /dev/null +++ b/task/download.go @@ -0,0 +1,6 @@ +package task + +var ( + DownloadUrl = "" + DownloadNum int +)