我正在为map[string]接口{}编写一个散列函数
大多数散列库需要[]字节作为输入来计算散列。
我尝试使用json.Marshal对简单的Map进行编组,它可以正确工作,但是当我添加一些复杂性并对项目进行洗牌时,json.Marshal无法给予一致的字节数组输出
package main
import (
"encoding/json"
"fmt"
)
func main() {
data := map[string]interface{}{
"id": "124",
"name": "name",
"count": 123456,
"sites": []map[string]interface{}{
{
"name": "123445",
"count": 234324,
"id": "wersfs",
},
{
"id": "sadcacasca",
"name": "sdvcscds",
"count": 22,
},
},
"list": []int{5, 324, 123, 123, 123, 14, 34, 52, 3},
}
data1 := map[string]interface{}{
"name": "name",
"id": "124",
"sites": []map[string]interface{}{
{
"id": "sadcacasca",
"count": 22,
"name": "sdvcscds",
},
{
"count": 234324,
"name": "123445",
"id": "wersfs",
},
},
"count": 123456,
"list": []int{123, 14, 34, 52, 3, 5, 324, 123, 123},
}
jsonStr, _ := json.Marshal(data)
jsonStr1, _ := json.Marshal(data1)
fmt.Println(jsonStr)
fmt.Println(jsonStr1)
for i := 0; i < len(jsonStr); i++ {
if jsonStr[i] != jsonStr1[i] {
fmt.Println("Byte arrays not equal")
}
}
}
这是我所尝试的,它未能给予我一个一致的输出。
此外,我想写一个函数,它将做排序的Map和价值观以及,但后来卡住了我如何排序
"sites": []map[string]interface{}
我试过json.Marshal和整理Map,但是卡住了
2条答案
按热度按时间kmpatx3s1#
你的数据结构是不等价的。根据JSON规则,数组是有序的,因此
[123, 14, 34, 52, 3, 5, 324, 123, 123]
和[5, 324, 123, 123, 123, 14, 34, 52, 3]
是不一样的。难怪哈希值是不同的。如果你需要相同元素的不同数组来产生相同的哈希值,你需要在哈希之前规范化数组。例如,对它们排序。以下是具体的操作方法:https://go.dev/play/p/OHq7jsX_cNw
在序列化之前,它递归地遍历Map和数组,并准备所有数组:
jjhzyzn02#
由于两个封送处理的输出基本上都是同一Map在不同序列中的字符串表示形式***,因此如果对它们的字符进行排序,它们将变得相等。
遵循此逻辑,如果您对jsonStr和jsonStr1进行排序,则排序后的[]byte***将完全相等。然后您可以使用它来表示散列值。
检查我的解决方案here