分析某款go端口扫描器之一

一、概述

        进来在学go的端口检测部分,但是自己写遇到很多问题,又不知道从何入手,故找来网上佬们写的现成工具,学习一波怎么实现的。分析过程杂乱,没啥思路,勿喷。

项目来源:https://github.com/XinRoom/go-portScan/blob/main/util/file.go

二、目录结构分析

总体来说,这个工具主要三部分,cmd(主程序)、core(核心框架部分)、util(工具部分),后续的分析也从这三个部分开始讲解

三、util目录

此目录下主要有三个文件,分别为file.go、log.go、shuffle.go,以下逐一分析

1、file.go(逐行读取文件内容)

  • func GetLines(filename string) (out []string, err error)

主要内容为一个GetLines方法,其接收一个文件名作为参数,并返回文件中非空行的内容组成字符串切片和可能的错误,主要作用是逐行读取文件,并将非空行的内容添加到“out"切片中。

func GetLines(filename string) (out []string, err error) {if filename == "" {//先判断文件名是否为空,为空则提示错误return out, errors.New("no filename")}file, err := os.Open(filename)//打开文件if err != nil {return out, err}defer file.Close()//读取完记得关闭scanner := bufio.NewScanner(file)//读取文件的内容scanner.Split(bufio.ScanLines)//一行一行读取分隔for scanner.Scan() {//逐行读取并将文本内容追加到out切片中line := strings.TrimSpace(scanner.Text())if line != "" {out = append(out, line)}}return
}

2、log.go(日志记录)

  • func NewLogger(filename string, std bool) *log.Logger

主要内容为一个 NewLogger方法,它根据提供的参数创建一个新的日志记录器对象。该函数接受一个文件名和一个布尔值参数。

  • filename 参数用于指定日志输出的文件名,如果为空字符串则表示日志将输出到标准输出(stdout)。
  • std 参数是一个布尔值,如果设置为 true,则日志会同时输出到文件和标准输出;如果设置为 false,则只输出到文件。

这个函数的目的是根据参数创建一个日志记录器,可以指定输出到文件还是标准输出,并可以选择是否同时输出到文件和标准输出。

func NewLogger(filename string, std bool) *log.Logger {var out io.Writerif filename == "" {out = os.Stdout //如果传入的filename为空,将out设置为标准输出} else {//如果不为空,则打开这个文件,outFile, _ := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)if std {//如果 std为true,则将输出同时定向到标准输出和文件中,通过 io.MultiWriter 将os.Stdout 和打开的文件合并成一个多写入器out = io.MultiWriter(os.Stdout, outFile)} else {//如果 std 参数为 false,则直接将输出定向到打开的文件中out = outFile}}logger := log.New(out, "", 0)//使用 log.New 方法创建一个新的日志记录器对象 logger,将输出对象 out 作为日志记录器的输出,设置空的前缀,并且不添加任何额外的选项(flag)return logger
}

3、shuffle.go

主要包含3个方法:NewShuffle、Get、IsUint16InList,以及一个结构体Shuffle

  • type Shuffle struct

type Shuffle struct {rl   []uint16 // 乱序序列,存储的是一般轮次的乱序序列rl2  []uint16 // 最后一轮乱序序列(无法整除时使用)n    uint16   // 乱序精度,用来限制乱序序列的长度size uint64    //乱序序列的大小
}
  • func NewShuffle(size uint64) *Shuffle

函数接收一个 size 参数作为生成乱序序列的大小。

// NewShuffle 局部乱序
func NewShuffle(size uint64) *Shuffle {if size == 0 { //如果size为0, 返回nilreturn nil}sf := &Shuffle{size: size}// 创建一个新的 Shuffle 结构体,设置其 size 字段为传入的值if size > 100 {sf.n = 100 //如果size>100,设置乱序精度为100} else {sf.n = uint16(size)//否则设置乱序精度为size 的 uint16 类型。}//通过循环填充 rl 切片,创建一般轮次的乱序序列。//使用 rand 包生成随机数种子,对 rl 进行乱序化操作。//如果 size 无法整除 n,则设置 rl2 切片,并生成最后一轮乱序序列// 通用轮次sf.rl = make([]uint16, sf.n)for i := uint16(0); i < sf.n; i++ {sf.rl[i] = i}// 洗牌方法r := rand.New(rand.NewSource(int64(size)))r.Shuffle(int(sf.n), func(i, j int) {sf.rl[i], sf.rl[j] = sf.rl[j], sf.rl[i]})// 最后一轮无法整除时新建对应长度的rl2t := uint16(size % uint64(sf.n))if t != 0 {sf.rl2 = make([]uint16, t)for i := uint16(0); i < t; i++ {sf.rl2[i] = i}r.Shuffle(int(t), func(i, j int) {sf.rl2[i], sf.rl2[j] = sf.rl2[j], sf.rl2[i]})}return sf
}
  • func (sf *Shuffle) Get(index uint64) uint6

Get 方法接收一个索引 index,用于获取转换后的索引值。首先计算 t 为 index 对 sf.n 取模得到的结果。然后根据索引 index 与 n 的关系,决定使用哪个乱序序列。如果无法整除,则使用 rl2,否则使用 rl

// Get 根据索引获取转换后的索引值
func (sf *Shuffle) Get(index uint64) uint64 {t := index % uint64(sf.n)// 最后一轮无法整除时用rl2if index-t+uint64(sf.n) > sf.size {return index - t + uint64(sf.rl2[uint16(t)])}return index - t + uint64(sf.rl[uint16(t)])
}
  • func IsUint16InList(code uint16, list []uint16) bool

IsUint16InList 函数接收一个 code 和一个 list,用于判断 list 中是否存在 code。

它遍历 list 切片,如果发现存在与 code 相等的元素,则返回 true;如果遍历完 list 后都没有找到,则返回 false。

func IsUint16InList(code uint16, list []uint16) bool {for _, e := range list {if e == code {return true}}return false
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/182195.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何高效解析不定长度的协议帧

通信设计中考虑协议的灵活性&#xff0c;经常把协议设计成“不定长度”。一个实例如下图&#xff1a;锐米LoRa终端的通信协议帧。 如果一个系统接收上述“不定长度”的协议帧&#xff0c;将会有一个挑战--如何高效接收与解析。 为简化系统设计&#xff0c;我们强烈建议您采用“…

hql面试题之字符串使用split分割,并选择其中的一部分字段的问题

版本&#xff1a;20231109 1.题目&#xff1a; 有两张表,a表有id和abstringr两个字段&#xff0c;b表也有id和bstr两个字段&#xff0c;具体如下 A表&#xff1a; 1abc,bcd,cdf2123,456,789 B表: 1acddef2123456 在a表的abstring字段中用‘,’分割&#xff0c;并取出前两…

关于MySQL的66个问题

SQL基础掌握不错的小伙伴可以跳过这一部分。当然&#xff0c;可能会现场写一些SQL语句&#xff0c;SQ语句可以通过牛客、LeetCode、LintCode之类的网站来练习。 1. 什么是内连接、外连接、交叉连接、笛卡尔积呢&#xff1f; 内连接&#xff08;inner join&#xff09;&#xf…

05_MySQL主从复制架构

任务背景 ##一、真实案例 某同学刚入职公司&#xff0c;在熟悉公司业务环境的时候&#xff0c;发现他们的数据库架构是一主两从&#xff0c;但是两台从数据库和主库不同步。询问得知&#xff0c;已经好几个月不同步了&#xff0c;但是每天会全库备份主服务器上的数据到从服务…

k8s安装步骤

环境&#xff1a; 操作系统&#xff1a;win10 虚拟机&#xff1a;VMware linux发行版&#xff1a;CentOS7.9 CentOS镜像&#xff1a;CentOS-7-x86_64-DVD-2009 master和node节点通信的ip(master)&#xff1a; 192.168.29.164 0.检查配置 本次搭建的集群共三个节点&#xff0c;…

2023年【安全员-A证】考试题及安全员-A证最新解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 安全员-A证考试题考前必练&#xff01;安全生产模拟考试一点通每个月更新安全员-A证最新解析题目及答案&#xff01;多做几遍&#xff0c;其实通过安全员-A证模拟考试题很简单。 1、【多选题】下列关于高处作业吊篮叙…

【Redis基础】Redis基本的全局命令

✅作者简介&#xff1a;大家好&#xff0c;我是小杨 &#x1f4c3;个人主页&#xff1a;「小杨」的csdn博客 &#x1f433;希望大家多多支持&#x1f970;一起进步呀&#xff01; Redis基本的全局命令 1&#xff0c;KEYS命令 语法&#xff1a;KEYS pattern KEYS命令用来查询服…

Python内置类属性`__name__`属性的使用教程

更多Python学习内容&#xff1a;ipengtao.com Python中的__name__是一种内置的特殊属性&#xff0c;通常用于判断模块是作为主程序运行还是作为模块被导入。本文将深入讲解__name__属性的用法&#xff0c;通过丰富的示例代码展示其在不同情景下的应用。 模块作为主程序运行 当一…

统信UOS_麒麟KYLINOS上使用远程SSH连接的工具electerm

原文链接&#xff1a;统信UOS/麒麟KYLINOS上使用SSH工具electerm Hello&#xff0c;大家好啊&#xff01;在我们日常的工作和学习中&#xff0c;远程控制和管理服务器已经成为一项常见且必要的技能。尤其是对于IT专业人士和开发者来说&#xff0c;一个高效、稳定的远程SSH连接工…

一款LED段码显示屏驱动芯片方案

一、基本概述 TM1620是一种LED&#xff08;发光二极管显示器&#xff09;驱动控制专用IC,内部集成有MCU数字接口、数据锁存器、LED驱动等电路。本产品质量可靠、稳定性好、抗干扰能力强。 二、基本特性 采用CMOS工艺 显示模式&#xff08;8段6位&#xff5e;10段4位&#xff…

模拟Spring源码思想,手写源码,理解@Component,@Value,@Autowired,@Qualifier四个注解

1、BeanDefinition package com.csdn.myspring; import lombok.AllArgsConstructor; import lombok.Data; Data AllArgsConstructor public class BeanDefinition {private String beanName;private Class beanClass; }2、扫描包的工具类MyTools package com.csdn.myspring; im…

排序算法基本原理及实现2

&#x1f4d1;打牌 &#xff1a; da pai ge的个人主页 &#x1f324;️个人专栏 &#xff1a; da pai ge的博客专栏 ☁️宝剑锋从磨砺出&#xff0c;梅花香自苦寒来 &#x1f324;️冒泡排序 &#x1…

简单位运算

文章目录 求 n n n 的第 k k k 位是二进制的几lowbit(n)操作求解 n n n 的最后一个 1 1 1题目练习AcWing 801. 二进制中1的个数CODE1 原码、补码、反码 求 n n n 的第 k k k 位是二进制的几 我们需要用到&运算符&#xff1a;两位都为 1 1 1 时结果才为 1 1 1 &…

Linux小程序之进度条

> 作者简介&#xff1a;დ旧言~&#xff0c;目前大二&#xff0c;现在学习Java&#xff0c;c&#xff0c;c&#xff0c;Python等 > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;自己能实现进度条 > 毒鸡汤&#xff1a; > …

制作心理咨询小程序的详细指南

随着科技的的发展&#xff0c;小程序已经成为了人们日常生活中不可或缺的一部分。特别是在心理咨询这个领域&#xff0c;小程序可以提供一个更为便捷、高效的服务平台。本文将通过乔拓云平台为例&#xff0c;详细介绍如何制作一个心理咨询小程序。 首先&#xff0c;我们需要注册…

【软件测试】盘一盘工作中遇到的 Redis 异常测试

在测试工作中&#xff0c;涉及到与 redis 交互的场景变的越来越多了。关于redis本身就不作赘述了&#xff0c;网上随便搜&#xff0c;本人也做过一些整理。 今天只来复盘一下&#xff0c;在测试过程中与 redis 的二三事儿。其中提到的案例是经过抽象化的&#xff0c;用作辅助说…

【SpringCloud系列】@FeignClient微服务轻舞者

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

基于Java web的多功能游戏大厅系统的开发与实现

摘 要 目前&#xff0c;国内游戏市场上的网络游戏有许多种类&#xff0c;游戏在玩法上也越来越雷同&#xff0c;形式越来越单调。这种游戏性系统给玩家带来的成就感虽然是无穷的&#xff0c;但是也有随之而来的疲惫感&#xff0c;尤其是需要花费大量的时间和精力&#xff0c;这…

Findreport中框架图使用的注意事项

目录 简介 测试数据 闭环链路关系 解决办法&#xff1a; 根不唯一 解决办法&#xff1a; 简介 在框架图的应用中&#xff0c;一些表达上下游关系的数据非常适合用于做链路图相关的报表。可以展示成雪花图&#xff0c;普通架构图。但是在实际操作中有几点关于数据的注意事…

【STM32】OLED显示屏

1 调试方式 1. 串口调试&#xff1a;通过串口通信&#xff0c;将调试信息发送到电脑端&#xff0c;电脑使用串口助手显示调试信息 2. 显示屏调试&#xff1a;直接将显示屏连接到单片机&#xff0c;将调试信息打印在显示屏上 3. Keil调试模式&#xff1a;借助Keil软件的调试模…