Golang实现一个批量自动化执行树莓派指令的软件(1)文本加密配置命令行交互实现

devtools/2024/9/25 9:40:52/

简介

实现一个在配置文件设置信息,一运行就可以自动执行设定指令的软件。
这次实现的是 :
1. 加密解密模块, 用于加密密码, 在配置时配置已加密的密码就可以;
2. 需要配置,自然也就有配置文件的序列化反序列化;
3. 这么多操作如果都放到一个文件执行就需要命令行指令知道当前该执行的动作, 所以还有个命令行交互

环境描述

运行环境: Windows, 基于Golang, 暂时没有使用什么不可跨平台接口, 理论上支持Linux/MacOS
目标终端树莓派DebianOS(主要做用它测试)

实现

加密解密

package utilsimport ("bytes""crypto/aes""crypto/cipher""crypto/rand""encoding/base64""io"
)type Encryption struct {Key []byte
}func NewEncryption(key string) *Encryption {return &Encryption{Key: []byte(key)}
}func (e *Encryption) Encrypt(text string) (string, error) {block, err := aes.NewCipher(e.Key)if err != nil {return "", err}textBytes := []byte(text)// 对于CBC模式,需要使用PKCS#7填充plaintext到blocksize的整数倍textBytes = e.pad(textBytes, aes.BlockSize)ciphertext := make([]byte, aes.BlockSize+len(textBytes))iv := ciphertext[:aes.BlockSize]if _, err := io.ReadFull(rand.Reader, iv); err != nil {return "", err}mode := cipher.NewCBCEncrypter(block, iv)mode.CryptBlocks(ciphertext[aes.BlockSize:], textBytes)return base64.StdEncoding.EncodeToString(ciphertext), nil
}func (e *Encryption) Decrypt(text string) (string, error) {data, err := base64.StdEncoding.DecodeString(text)if err != nil {return "", err}block, err := aes.NewCipher(e.Key)if err != nil {return "", err}if len(data) < aes.BlockSize {return "", err}iv := data[:aes.BlockSize]data = data[aes.BlockSize:]mode := cipher.NewCBCDecrypter(block, iv)mode.CryptBlocks(data, data)data = e.unpad(data, aes.BlockSize)return string(data), nil
}// pad 使用PKCS#7标准填充数据
func (e *Encryption) pad(buf []byte, blockSize int) []byte {padding := blockSize - (len(buf) % blockSize)padtext := bytes.Repeat([]byte{byte(padding)}, padding)return append(buf, padtext...)
}// unpad 移除PKCS#7标准填充的数据
func (e *Encryption) unpad(buf []byte, blockSize int) []byte {if len(buf)%blockSize != 0 {return nil}padding := int(buf[len(buf)-1])return buf[:len(buf)-padding]
}

配置

isettings.go

package utilsimport ("errors"
)type SettingsType intconst (SETTINGS_JSON SettingsType = 0
)type ISettings interface {FromBytes(src []byte) errorToBytes() ([]byte, error)FromFile(filepath string) errorToFile(filepath string) errorData() interface{}
}func NewSettings(typ SettingsType, model interface{}) (ISettings, error) {if nil == model {return nil, errors.New("model == nil")}switch typ {case SETTINGS_JSON:return NewJsonSettings(model)default:return nil, errors.New("wrong setting type")}
}

jsonsettings.go

package utilsimport ("encoding/json""os"
)type JsonSettings struct {dat interface{}
}func NewJsonSettings(v interface{}) (ISettings, error) {cfg := &JsonSettings{dat: v}return cfg, nil
}func (c *JsonSettings) FromBytes(src []byte) error {return json.Unmarshal(src, c.dat)
}func (c *JsonSettings) ToBytes() ([]byte, error) {return json.MarshalIndent(c.dat, "", "  ")
}func (c *JsonSettings) FromFile(filepath string) error {bs, err := os.ReadFile(filepath)if nil != err {return err}err = c.FromBytes(bs)return err
}func (c *JsonSettings) ToFile(filepath string) error {bs, err := c.ToBytes()if nil != err {return err}err = os.WriteFile(filepath, bs, 0666)return err
}func (c *JsonSettings) Data() interface{} {return c.dat
}

命令行交互

package cmdimport ("github.com/spf13/cobra""os"
)var rootCommand = rootCmd()/*
所有指令初始化
*/
func init() {rootCommand.AddCommand(runCmd())rootCommand.AddCommand(versionCmd())rootCommand.AddCommand(initCmd())rootCommand.AddCommand(encryptCmd())
}func rootCmd() *cobra.Command {var cmd = &cobra.Command{Use:   "ssh_remote_access",Short: "SSH Remote Access Tool",Long:  "SSH Remote Access Tool, get help from https://listentome.blog.csdn.net/",Run:   rootRun,}cmd.Flags().BoolP("run", "r", false, "run job list")cmd.Flags().BoolP("init", "i", false, "initialize the tool")cmd.Flags().BoolP("version", "v", false, "get version")cmd.Flags().StringP("encrypt", "e", "", "encrypt the string")return cmd
}func rootRun(cmd *cobra.Command, args []string) {var cmdStrings = []string{"run", "init", "version", "encrypt"}var matchCmd stringfor _, v := range cmdStrings {var flag = cmd.Flag(v)if flag != nil && flag.Changed {matchCmd = vbreak}}if matchCmd == "" {matchCmd = "help"cmd.Help()return}for _, v := range cmd.Commands() {if v.Name() == matchCmd {v.Run(cmd, args)return}}
}func Execute() error {rootCommand.SetArgs(os.Args[1:])return rootCommand.Execute()
}

代码源

https://gitee.com/grayhsu/ssh_remote_access

其他

参考


http://www.ppmy.cn/devtools/16485.html

相关文章

数据存储基础——存储类型

数据存储 数据存储之定义数据存储设备直接区域存储&#xff08;DAS&#xff09;基于网络的存储网络连接存储 (NAS)存储区域网络 (SAN)对象存储 IT互联网公司常用的存储方案包括&#xff1a;存储汇总信息 数据存储之定义 数据存储是指磁性、光学或机械介质&#xff0c;用于记录…

Hadoop 启动!

​2024/4/22 上个星期我们已经完成了Hadoop的安装及配置文件的修改 下面 我们将namenode进行一下初始化 hdfs namenode -format (创建文件存储目录&#xff1a;账本目录namenode datanode的目录) 我们在配置时 这就是用来设置账本目录的 我们做完格式化后 tmp目录就出现了 …

Opencv Python图像处理笔记一:图像、窗口基本操作

文章目录 前言一、输入输出1.1 图片读取显示保存1.2 视频读取保存1.3 文件读取保存 二、GUI2.1 窗口2.2 轨迹条2.3 画图2.4 鼠标回调 三、图像入门操作3.1 颜色空间转化3.2 通道分离合并3.3 添加边框3.4 算数操作 四、二值化4.1 普通4.2 自适应4.3 Otsu 参考 前言 随着人工智能…

vue3 子组件实现v-model用法

在Vue 3中&#xff0c;实现自定义的input组件并支持v-model绑定&#xff0c;涉及到对modelValue这个默认prop的处理和对应的update:modelValue事件的触发。Vue 3使得这个过程比Vue 2更为简化和灵活&#xff0c;尤其是在可以自定义绑定的属性和事件名方面。 步骤 1: 创建自定义…

AI Agent新对决:LangGraph与AutoGen的技术角力

AI Agent变革未来&#xff0c;LangGraph对抗AutoGen ©作者|Blaze 来源|神州问学 引言 比尔.盖茨曾在他的博客上发表一篇文章&#xff1a;《AI is about to completely change how you use computers》。在文章中&#xff0c;比尔盖茨探讨AI Agent对我们未来生活的巨大影…

微信小程序有的机型无法播放m3u8格式的直播流,使用H5在微信环境里播放

我这测试鸿蒙的还有苹果X及部分机型在微信小程序里无法播放&#xff0c;不知道什么原因&#xff1b; 直播流地址有的是hevc有的是h.264&#xff0c;音频都是aac&#xff1b; <head><meta charset"UTF-8"><title>前端播放m3u8格式视频</title&g…

Python函数小知识

目录 一、函数的定义和调用 二、函数参数 三、函数作用域 四、递归函数和匿名函数 一、函数的定义和调用 def 函数名(参数): 自定义函数可以分为有参函数和无参函数 。 函数的作用&#xff1a; 在Python中定义函数可以提高代码的复用率&#xff0c;避免重复的代码&#xff0c;…

ESP32开发WebSocket报错TRANSPORT_WS: Sec-WebSocket-Accept not found

我的芯片是ESP32-S3&#xff0c;用ESP-IDF框架进行开发的时候&#xff0c;用官方的WebSocket的example创建了项目。然后把WebSocket连接uri替换为自己的服务器后&#xff0c;运行到esp_websocket_client_start开始连接后&#xff0c;直接报错&#xff1a; E (10615) TRANSPORT…