1.思路
今天在看一本区块链的书籍发现了区块链头部有存储梅克尔树根哈希值,感觉这个梅克尔树根哈希值真是非常厉害,简单的一段文本就可以保证所有数据不被修改。算法思路也很简单,就自己实现了下,就是两两组合求sha256值。
2.代码
package main
import (
"crypto/sha256"
"encoding/hex"
"fmt"
)
func GetHash256(str string) string {
hash := sha256.New()
hash.Write([]byte(str))
sum := hash.Sum(nil)
return hex.EncodeToString(sum)
}
// 梅克尔树根哈希值计算算法
// hashs 要计算的哈希值
// 返回树根哈希值
func MerkleRoot(args []string) string {
// 获取参数的个数
nums := len(args)
var odd string
if len(args) == 1 {
return GetHash256(args[0])
}
// 先对所有元素进行取哈希
for i, arg := range args {
args[i] = GetHash256(arg)
}
var layer = 0 // 表示层数
// 循环到args中只有一个元素为止
for len(args) != 1 {
// 判断参数是否是偶数
if nums%2 != 0 {
// 奇数
if layer == 0 {
// 保存最后一个元素
odd = args[len(args)-1]
// 删除最后一个元素
args = args[0 : len(args)-1]
} else {
// 判断odd是否为空
if len(odd) != 0 {
args = append(args, odd)
odd = ""
}
}
}
// 临时args
temp_args := make([]string, 0)
//两两取哈希
for i := 0; i < len(args)-1; i = i + 2 {
temp_args = append(temp_args, GetHash256(args[i]+args[i+1]))
}
args = temp_args
temp_args = nil
layer++
}
return args[0]
}
func main() {
var nums = []string{"hello", "go", "i", "love"}
fmt.Printf("content : %v", MerkleRoot(nums))
}
/*
输出结果:
layer : 0 , content : [a70c498f438b10cfbd088695fef532afd33d7f7094de8c617296d068298744ca 72b39755c651fdd470759d845addf2f7bd7ceae67e1141be234225a13fcac1b1]
layer : 1 , content : [2ebccf55e07779f2d23fa765e8ddcaaa923e408bf4d321bae88fd09b22ce07ae]
content : 2ebccf55e07779f2d23fa765e8ddcaaa923e408bf4d321bae88fd09b22ce07ae
*/