Golang哈希算法實(shí)現(xiàn)配置文件的監(jiān)控功能詳解
SHA(secure hashing algorithm)表示安全哈希算法.SHA是MD5的修正版本,用于數(shù)據(jù)摘要和認(rèn)證。哈希和加密類(lèi)似,唯一區(qū)別是哈希是單項(xiàng)的,即哈希后的數(shù)據(jù)無(wú)法解密。SHA有不同的算法,主要包括SHA-1, SHA-2, SHA-256, SHA-512, SHA-224, and SHA-384等,其中SHA-256是SHA-2家族的一個(gè)成員,它把原數(shù)據(jù)轉(zhuǎn)為256字節(jié)固定長(zhǎng)度摘要信息,SHA256的內(nèi)部塊大小為32位。本文介紹Golang如何使用sha256算法實(shí)現(xiàn)對(duì)配置文件的監(jiān)控。
Golang hash256實(shí)現(xiàn)包
hash256包實(shí)現(xiàn)了FIPS 180-4規(guī)范中定義的SHA224、SHA256哈希算法。主要包括下面幾個(gè)函數(shù):
func New() hash.Hash: 返回 hash.Hash,用于計(jì)算SHA256哈希值。
func Sum256(data []byte) [Size]byte :返回計(jì)算SHA256的哈希值。
使用sha256.New()
下面示例使用New()函數(shù)返回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))
}
過(guò)程很簡(jiǎn)單,運(yùn)行輸出結(jié)果:
289ca48885442b5480dd76df484e1f90867a2961493b7c60e542e84addce5d1e
使用sha256.Sum256()函數(shù)
package main
import (
"crypto/sha256"
"fmt"
)
func main() {
sum := sha256.Sum256([]byte("this is a password"))
fmt.Printf("%x", sum)
}
更簡(jiǎn)潔,輸出結(jié)果一樣。
下面示例展示兩個(gè)字符串,盡管只有一個(gè)字符微小差異,但生成的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)
}
運(yùn)行輸出結(jié)果:
lowercase hash: 289ca48885442b5480dd76df484e1f90867a2961493b7c60e542e84addce5d1e
Capital hash: 9ae12b1403d242c53b0ea80137de34856b3495c3c49670aa77c7ec99eadbba6e

監(jiān)控配置文件變化
我們需要觀察文件是否變化,標(biāo)準(zhǔn)實(shí)現(xiàn)使用time.Ticker每隔幾秒重新計(jì)算配置文件的哈希值,如果哈希值發(fā)生變化,則重新加載。
獲取配置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
}
上面方法步驟:
- 打開(kāi)配置文件
- 從crypto/sha256創(chuàng)建hash.Hash對(duì)象
- 解析文件內(nèi)容到hash對(duì)象
- 調(diào)用Sum方法獲得hash值
上面示例中test測(cè)試文件,可以隨便輸入一些內(nèi)容,生成文件hash值。
下面實(shí)現(xiàn)比較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值進(jìn)行比較,如不同則保存最新hash值用于下一次比較,同時(shí)調(diào)用RefreshCfg()方法,該方法是具體業(yè)務(wù)實(shí)現(xiàn),這里僅給出空實(shí)現(xiàn):
func RefreshCfg() {
fmt.Println(" refresh config information.")
}
最后是main函數(shù)部分:
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...")
}
}
}
首先保存當(dāng)前配置文件的Hash值。然后利用Ticker每2秒比較一次比較。運(yùn)行程序修改配置文件,可以立刻看到程序監(jiān)控到變化并調(diào)用RefreshCfg方法。
下面給出完整代碼實(shí)現(xiàn):
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
}總結(jié)
數(shù)據(jù)加密算法規(guī)范非常復(fù)雜,在大多數(shù)應(yīng)用場(chǎng)景中需要廣泛研究。但Golang提供了專(zhuān)門(mén)的庫(kù),實(shí)現(xiàn)了許多流行的加密算法。本文演示了如何使用crypto/sha256對(duì)配置文件進(jìn)行監(jiān)控,變化則重新加載配置文件。
到此這篇關(guān)于Golang哈希算法實(shí)現(xiàn)配置文件的監(jiān)控功能詳解的文章就介紹到這了,更多相關(guān)Golang哈希算法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Go語(yǔ)言實(shí)現(xiàn)開(kāi)發(fā)一個(gè)簡(jiǎn)單的gRPC Demo
這篇文章主要為大家詳細(xì)介紹了如何利用Go語(yǔ)言實(shí)現(xiàn)開(kāi)發(fā)一個(gè)簡(jiǎn)單的gRPC Demo,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解一下2023-07-07
Golang實(shí)現(xiàn)定時(shí)任務(wù)的幾種方法小結(jié)
在 Golang 開(kāi)發(fā)中,定時(shí)任務(wù)是常見(jiàn)的需求,本文將介紹幾種在 Golang 中實(shí)現(xiàn)定時(shí)任務(wù)的方法,包括 time 包的定時(shí)器、ticker,以及第三方庫(kù) cron,并通過(guò)示例代碼展示它們的使用方式,需要的朋友可以參考下2024-01-01
golang結(jié)構(gòu)化日志log/slog包之slog.Record的用法簡(jiǎn)介
這篇文章主要為大家詳細(xì)介紹了golang結(jié)構(gòu)化日志log/slog包中slog.Record結(jié)構(gòu)體的使用方法和需要注意的點(diǎn),文中的示例代碼講解詳細(xì),需要的可以學(xué)習(xí)一下2023-10-10
Golang中實(shí)現(xiàn)類(lèi)似類(lèi)與繼承的方法(示例代碼)
這篇文章主要介紹了Golang中實(shí)現(xiàn)類(lèi)似類(lèi)與繼承的方法,Go語(yǔ)言中通過(guò)方法接受者的類(lèi)型來(lái)決定方法的歸屬和繼承關(guān)系,本文通過(guò)示例代碼講解的非常詳細(xì),需要的朋友可以參考下2024-04-04
golang gorm 結(jié)構(gòu)體的表字段缺省值設(shè)置方式
這篇文章主要介紹了golang gorm 結(jié)構(gòu)體的表字段缺省值設(shè)置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12
golang實(shí)現(xiàn)微信小程序商城后臺(tái)系統(tǒng)(moshopserver)
這篇文章主要介紹了golang實(shí)現(xiàn)微信小程序商城后臺(tái)系統(tǒng)(moshopserver),本文通過(guò)截圖實(shí)例代碼的形式給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-02-02
go的defer和閉包示例說(shuō)明(非內(nèi)部實(shí)現(xiàn))
這篇文章主要為大家介紹了go的defer和閉包示例說(shuō)明(非內(nèi)部實(shí)現(xiàn)),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08
golang bad file descriptor問(wèn)題的解決方法
這篇文章主要給大家介紹了golang bad file descriptor問(wèn)題的解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-02-02

