基于Golang哈希算法监控配置文件变化

news2024/12/25 15:11:05

SHA(secure hashing algorithm)表示安全哈希算法.SHA是MD5的修正版本,用于数据摘要和认证。哈希和加密类似,唯一区别是哈希是单项的,即哈希后的数据无法解密。SHA有不同的算法,主要包括SHA-1, SHA-2, SHA-256, SHA-512, SHA-224, and SHA-384等,其中SHA-256是SHA-2家族的一个成员,它把原数据转为256字节固定长度摘要信息,SHA256的内部块大小为32位。本文介绍Golang如何使用sha256算法实现对配置文件的监控。

Golang hash256实现包

hash256包实现了FIPS 180-4规范中定义的SHA224、SHA256哈希算法。主要包括下面几个函数:

func New() hash.Hash: 返回 hash.Hash,用于计算SHA256哈希值。

func Sum256(data []byte) [Size]byte :返回计算SHA256的哈希值。

使用sha256.New()

下面示例使用New()函数返回Hash.hash:

package main

import (
	"crypto/sha256"
	"fmt"
)

func main() {
	h := sha256.New()
	h.Write([]byte("this is a password"))

	// Calculate and print the hash
	fmt.Printf("%x", h.Sum(nil))
}

过程很简单,运行输出结果:

289ca48885442b5480dd76df484e1f90867a2961493b7c60e542e84addce5d1e

使用sha256.Sum256()函数

package main

import (
	"crypto/sha256"
	"fmt"
)

func main() {
	sum := sha256.Sum256([]byte("this is a password"))
	fmt.Printf("%x", sum)
}

更简洁,输出结果一样。

下面示例展示两个字符串,尽管只有一个字符微小差异,但生成的hash却完全不同:

package main

import (
	"crypto/sha256"
	"fmt"
)

func main() {
	sum := sha256.Sum256([]byte("this is a password"))
	sumCap := sha256.Sum256([]byte("This is a password"))
	fmt.Printf("lowercase hash: %x", sum)
	fmt.Println("")
	fmt.Printf("Capital hash: %x", sumCap)
}

运行输出结果:

lowercase hash: 289ca48885442b5480dd76df484e1f90867a2961493b7c60e542e84addce5d1e
Capital   hash: 9ae12b1403d242c53b0ea80137de34856b3495c3c49670aa77c7ec99eadbba6e

在这里插入图片描述

监控配置文件变化

我们需要观察文件是否变化,标准实现使用time.Ticker每隔几秒重新计算配置文件的哈希值,如果哈希值发生变化,则重新加载。

获取配置hash值

func getCfgHash() string {
	file, err := os.Open("test.cfg")
	defer file.Close()
	if err != nil {
		panic(err)
	}

	hash := sha256.New()
	if _, err := io.Copy(hash, file); err != nil {
		panic(err)
	}
	sum := fmt.Sprintf("%x", hash.Sum(nil))

	return sum
}

上面方法步骤:

  1. 打开配置文件
  2. 从crypto/sha256创建hash.Hash对象
  3. 解析文件内容到hash对象
  4. 调用Sum方法获得hash值
    上面示例中test测试文件,可以随便输入一些内容,生成文件hash值。

下面实现比较hash值方法:

func compare(new string) bool {
	var oldStr = ""

	oldFile, _ := os.Open("tmp.hash")
	oldBytes, _ := io.ReadAll(oldFile)
	oldStr = string(oldBytes)
	oldFile.Close()

	if oldStr != new {
		newFile, _ := os.Create("tmp.hash")
		fmt.Println("new hash:", new)
		newFile.WriteString(new)

		RefreshCfg()
		return false
	}
	return true
}

先加载上一次保存的配置文件hash值,与本次传入最新hash值进行比较,如不同则保存最新hash值用于下一次比较,同时调用RefreshCfg()方法,该方法是具体业务实现,这里仅给出空实现:

func RefreshCfg() {
	fmt.Println(" refresh config information.")
}

最后是main函数部分:

func main() {
	// 先记录配置文件hash值
	cfgHash := getCfgHash()
	fmt.Println("cfg hash:", cfgHash)

	file, _ := os.Create("tmp.hash")
	file.WriteString(cfgHash)
	file.Close()

	// define an interval and the ticker for this interval
	interval := time.Duration(2) * time.Second
	// create a new Ticker
	tk := time.NewTicker(interval)

	// start the ticker by constructing a loop
	for range tk.C {
		fmt.Println("time running...")

		loadStr := getCfgHash()
		if !compare(loadStr) {
			fmt.Println("config file has changed...")
		}
	}
}

首先保存当前配置文件的Hash值。然后利用Ticker每2秒比较一次比较。运行程序修改配置文件,可以立刻看到程序监控到变化并调用RefreshCfg方法。

下面给出完整代码实现:

package main

import (
	"crypto/sha256"
	"time"

	"fmt"
	"io"
	"os"
)

func main() {
	// 先记录配置文件hash值
	cfgHash := getCfgHash()
	fmt.Println("cfg hash:", cfgHash)

	file, _ := os.Create("tmp.hash")
	file.WriteString(cfgHash)
	file.Close()

	// define an interval and the ticker for this interval
	interval := time.Duration(2) * time.Second
	// create a new Ticker
	tk := time.NewTicker(interval)

	// start the ticker by constructing a loop
	for range tk.C {
		fmt.Println("time running...")

		loadStr := getCfgHash()
		if !compare(loadStr) {
			fmt.Println("config file has changed...")
		}
	}
}

func RefreshCfg() {
	fmt.Println(" refresh config information.")
}

func getCfgHash() string {
	file, err := os.Open("test.cfg")
	defer file.Close()
	if err != nil {
		panic(err)
	}

	hash := sha256.New()
	if _, err := io.Copy(hash, file); err != nil {
		panic(err)
	}
	sum := fmt.Sprintf("%x", hash.Sum(nil))

	return sum
}

func compare(new string) bool {
	var oldStr = ""

	oldFile, _ := os.Open("tmp.hash")
	oldBytes, _ := io.ReadAll(oldFile)
	oldStr = string(oldBytes)
	oldFile.Close()

	if oldStr != new {
		newFile, _ := os.Create("tmp.hash")
		fmt.Println("new hash:", new)
		newFile.WriteString(new)

		RefreshCfg()
		return false
	}
	return true
}

总结

数据加密算法规范非常复杂,在大多数应用场景中需要广泛研究。但Golang提供了专门的库,实现了许多流行的加密算法。本文演示了如何使用crypto/sha256对配置文件进行监控,变化则重新加载配置文件。

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

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

相关文章

1.2.6存储结构-磁盘管理:单缓冲区与双缓冲区读取、流水线周期、计算流水线执行时间

1.2.6存储结构-磁盘管理:单缓冲区与双缓冲区读取、流水线周期、计算流水线执行时间流水线周期计算流水线执行时间微秒,时间单位,符号μs(英语:microsecond ),1微秒等于百万分之一秒(…

SpringSecurity的使用与步骤

1、SpringSecurity流程图2、导入坐标<!-- spring-boot-starter-security --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId> </dependency> <!-- jjwt…

生物素-磺基-活性酯,Sulfo-NHS Biotin科研用试剂简介;CAS:119616-38-5

生物素-磺基-活性酯,Sulfo-NHS Biotin 结构式&#xff1a; ​ 编辑 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 英文名称&#xff1a;Sulfo-NHS-Biotin Sulfosuccinimidyl biotin 中文名称&#xff1a;磺酸基-Biotin-N-琥珀酰亚胺基酯 CAS&…

自己总结优化代码写法

jdk1.7新特性详解 开发期间略知jdk1.7的一些特性&#xff0c;没有真正的一个一个得展开研究&#xff0c;而是需要说明再去查&#xff0c;导致最整个新特性不是特别的清楚&#xff0c;这种情况以后得需要改变了&#xff0c;否则就会变成代码的奴隶。现在正好有时间可以细细的研…

SpringCloud第二讲 Ribbon负载均衡源码分析

前言介绍&#xff1a; 这一讲我们将依据Eureka的负载均衡规则&#xff0c;Eureka的具体服务搭建以及服务注册和服务发现可以参考基于Eureka实现服务注册和服务发现_热爱Java的编程小白的博客-CSDN博客 Eureka的服务搭建之后便可以在这上面进行服务注册&#xff0c;如果存在两个…

产品权限分析与设计

目前我们使用的访问控制授权方案&#xff0c;主要有以下4种&#xff1a;DAC自主访问控制ACL 访问控制列表MAC强制访问控制RBAC 基于角色的访问控制笔者将拆解和分析这4种权限管理方案的逻辑&#xff0c;并告诉你&#xff0c;这4种权限分别可以运用在什么样的场景中&#xff0c;…

不能注册?让小白也能使用【ChatGPT】

ChatGPT介绍最近ChatGPT可谓是非常火爆&#xff0c;使得互联网各界人士都备受关注&#xff0c;如果你还不了解ChatGPT,那你真的有点落后了哈。 简单介绍一下ChatGPTChatGPT是由美国人工智能OpenAI研究开发的一种全新聊天机器人模型&#xff0c;它能够通过学习和理解人类的语言跟…

研一寒假C++复习笔记--左值和右值的理解和使用

目录 1--左值和右值的定义 2--简单理解左值和右值的代码 3--非const引用只能接受左值 1--左值和右值的定义 左值&#xff1a;L-Value&#xff0c;L理解为 Location&#xff0c;表示可寻&#xff1b; 右值&#xff1a;R-Value&#xff0c;R理解为 Read&#xff0c;表示可读&a…

Windows 安装appium环境

1 windows Appium环境 1.1 安装Node.js Node.js的安装相对简单,下载安装包安装&#xff08;安装包node-v19.6.0-x64.msi&#xff09;, nodejs 安装 然后一路狂点下一步就可以了 安装完成后,在终端中输入node -v,显示版本号则表示安装成功 node-v16.13.1 1.2 JDK安装及环境变…

路由器刷固件

前言 我希望可以远程访问我的电脑。但&#xff0c;我不希望电脑总是处于运行状态&#xff0c;因为那样比较费电。所以需要一个方案&#xff0c;能将睡眠/关机中的电脑唤醒。 方案一&#xff1a;选用智能插座&#xff0c;远程给电脑上电。电脑设置上电自启。但&#xff0c;这存…

试题 算法训练 N皇后问题(明确清晰)

试题 算法训练 N皇后问题 提交此题 评测记录 资源限制 内存限制&#xff1a;256.0MB C/C时间限制&#xff1a;100ms Java时间限制&#xff1a;300ms Python时间限制&#xff1a;500ms 问题描述   在N*N的方格棋盘放置了N个皇后&#xff0c;使得它们不相互攻击&#xff08;即…

色彩-基础理论

颜色三大指标 色相 色相是颜色的一个属性&#xff0c;只有黑白灰没有色相这个属性(那银灰色是什么&#xff1f;) 颜色的相貌&#xff0c;指的也是给颜色一个名字 例如&#xff1a;暗红、酒红、土黄、墨绿 饱和度 颜色的鲜艳程度 纯度 饱和度主要取决于含色成分和消色成分&a…

IDE2022源码编译tomcat

因为学习需要&#xff0c;我需要源码编译运行tomcat对其源码进行一个简单的追踪分析。由于先前并未接触过java相关的知识&#xff0c;安装阻力巨大。最后请教我的开发朋友才解决了最后的问题。将其整理出来&#xff0c;让大家能够快速完成相关的部署。本文仅解决tomcat-8.5.46版…

tensorflow.js 视频图片多目标检测

前言&#xff1a;Tensorflow.js 官方提供了很多常用模型库&#xff0c;涵盖了平时开发中大部分场景的模型。例如&#xff0c;前面提到的图片识别&#xff0c;除此之外还有人体姿态识别&#xff0c;目标物体识别&#xff0c;语音文字等识别。其中一些可能是 Python 转换而来&…

前后端RSA互相加解密、加签验签、密钥对生成(Java)

目录一、序言二、关于PKCS#1和PKCS#8格式密钥1、简介2、区别二、关于JSEncrypt三、关于jsrsasign四、前端RSA加解密、加验签示例1、相关依赖2、cryptoUtils工具类封装3、测试用例五、Java后端RSA加解密、加验签1、CryptoUtils工具类封装2、测试用例六、前后端加解密、加验签交互…

导数与微分总复习——“高等数学”

各位CSDN的uu们你们好呀&#xff0c;今天&#xff0c;小雅兰来复习一下之前学过的知识点&#xff0c;也就是导数与微分的总复习&#xff0c;依旧是高等数学的内容&#xff0c;主要是明天就要考高等数学了&#xff0c;哈哈哈&#xff0c;下面&#xff0c;让我们一起进入高等数学…

取电芯片全协议都可兼容

乐得瑞PD协议芯片/PD取电芯片/PD受电端协议芯片 支持5/9/12/15/20v定制 1、概述 LDR6328S 是乐得瑞科技有限公司开发的一款兼容 USB PD、QC 和 AFC 协议的 Sink 控制器。 LDR6328S 从支持 USB PD、QC 和 AFC 协议的适配器取电&#xff0c;然后供电给设备。比如可以配置适配器输…

二十九、异常处理

目录 ①前言: ②常见的运行时异常 ③常见的编译时异常 ④异常的处理机制 ⑤自定义异常 ①前言: 1.什么是异常&#xff1f; 异常是程序在“编译”或者“执行”的过程中可能出现的问题&#xff0c;注意&#xff1a;语法错误不算在异常体系中。 比如: 数据索引越界异常&…

C语言的程序环境和预处理详解

目录 一、程序的翻译环境和执行环境 二、编译和链接详解 2、1 翻译环境 2、2 编译过程详解 2、3 执行环境 三、预处理详解 3、1 预定义符号 3、2 #define 3、2、1 #define定义的符号 3、2、2 #define 定义宏 3、2、3 #define 替换规则 3、3 宏和函数的对比 3、4 条件编译 3、5…

CUDA中的底层驱动API

文章目录CUDA底层驱动API1. Context2. Module3. Kernel Execution4. Interoperability between Runtime and Driver APIs5. Driver Entry Point Access5.1. Introduction5.2. Driver Function Typedefs5.3. Driver Function Retrieval5.3.1. Using the driver API5.3.2. Using …