我希望能够在 Go 中创建可重复的结构字节数组,以便我可以对它们进行哈希处理,然后在某个时候验证该哈希值。
我目前正在按照这种简单的方法从结构中创建一个字节数组:
[]byte(fmt.Sprintf("%v", struct))...)
在我的结构包含一个带有指针的嵌入式结构之前,这非常有效,例如:
type testEmbeddedPointerStruct struct {
T *testSimpleStruct
}
在我的测试中,这每次都会创建一个不同的字节数组,我认为这可能是因为指针每次都会改变内存中的地址?
即使结构包含指针,是否有办法创建可重复的字节数组摘要?
谢谢
最佳答案
... I think it may be because with the pointer the address in memory changes ...
那是显而易见的候选人,是的。您选择了一种非常简单的编码,其中指针字段被编码为指针的十六进制表示,而不是在指针目标处找到的任何值。
Is there a way of creating a repeatable byte array digest even if the struct holds a pointer?
您可能需要更准确地定义“相同值的重复”对您意味着什么,1 但总的来说,这确实是一个编码问题。
encoding/gob
包可能会给你一个你想要的编码,但请注意,与 %v
不同。格式化,它只对导出的结构字段进行编码并保留各种名称。它具有“展平”任何指针数据的效果,但不适用于循环数据结构。(您可以编写自己的更简单的编码器,在遇到指针时简单地跟随指针,否则像
%v
一样工作。)1例如,假设您有:
type T struct {
I int
P *Sub
}
type Sub struct {
J int
}
// ...
s2 := Sub{2}
s3 := Sub{3}
t1 := T{1, &s2}
t2 := T{1, &s3}
显然打印 t1 和 t2(同时压平指针)会产生
{1 2}
的编码版本和 {1 3}
分别,所以这些不是相同的值。但是,如果我们更改 s3
本身:s3 := Sub{2}
我们现在有两个不同的实体,
t1
和 t2
,两者都“包含为值”{1 2}
.在围棋中,t1
和 t2
是不同的,因为它们的指针不同。换句话说,他们的值(value)观是不同的。在建议的编码中,t1
和 t2
两者编码相同,因此它们的值相同。这就是指针所发生的事情:底层数据可能是相同的——在某种意义上是“相同的值”——但持有这些值的对象可能在位置上不同,所以如果一个对象被修改,另一个对象是不是。如果您通过使它们共享指向值的编码然后解码过程来运行此类对象,则您可能会放弃修改一个对象而不修改另一个对象或区分它们的能力。
由于您可以选择如何进行编码,因此您可以准确地决定您希望在这里发生什么。但是你必须有目的地做出这个选择,而不是偶然。
关于go - 创建包含指针的 Go 结构的可重复字节数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61910322/