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

简介

实现一个在配置文件设置信息,一运行就可以自动执行设定指令的软件。

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

环境描述

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

实现

加密解密

cpp 复制代码
package utils

import (
	"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

cpp 复制代码
package utils

import (
	"errors"
)

type SettingsType int

const (
	SETTINGS_JSON SettingsType = 0
)

type ISettings interface {
	FromBytes(src []byte) error
	ToBytes() ([]byte, error)

	FromFile(filepath string) error
	ToFile(filepath string) error

	Data() 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

go 复制代码
package utils

import (
	"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
}

命令行交互

go 复制代码
package cmd

import (
	"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 string
	for _, v := range cmdStrings {
		var flag = cmd.Flag(v)
		if flag != nil && flag.Changed {
			matchCmd = v
			break
		}
	}

	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

其他

参考

相关推荐
纳米软件5 小时前
电源模块纹波与噪声测试:从原理到自动化实现
自动化·labview·电源测试系统·atecloud·零代码软件开发
卷福同学5 小时前
【养虾日记】QClaw操作浏览器自动化发文
运维·人工智能·程序人生·自动化
智_永无止境5 小时前
AI时代,一个Skill如何让Java项目结构自动化?
自动化·skills
新新学长搞科研7 小时前
第五届电子、集成电路与通信技术国际学术会议(EICCT 2026)
运维·人工智能·自动化·集成测试·信号处理·集成学习·电气自动化
阿达_优阅达8 小时前
告别手工对账:xSuite 如何帮助 SAP 企业实现财务全流程自动化?
服务器·数据库·人工智能·自动化·sap·企业数字化转型·xsuite
renhongxia19 小时前
多模态融合驱动下的具身学习机制研究
运维·学习·机器人·自动化·知识图谱
Chengbei1110 小时前
Chrome浏览器渗透利器支持原生扫描!JS 端点 + 敏感目录 + 原型污染自动化检测|VulnRadar
javascript·chrome·安全·web安全·网络安全·自动化·系统安全
fy1216310 小时前
GO 快速升级Go版本
开发语言·redis·golang
qq_5260991312 小时前
工业视觉时代,图像采集卡如何重构数据采集
图像处理·数码相机·计算机视觉·自动化
彷徨的蜗牛12 小时前
智能AI自动化协同发文系统架构设计:从理论到实践的完整指南
人工智能·系统架构·自动化