创建包含指针的 Go 结构的可重复字节数组

Create repeatable byte array of Go struct which contains a pointer

我希望能够在 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?

您可能需要更准确地定义 "repeat of same value" 对您意味着什么,1 但总的来说,这确实是一个编码问题。 encoding/gob 包可能会为您提供您想要的编码,但请注意,与 %v 格式不同,它仅对导出的结构字段进行编码 并且 保留各种名称.它具有 "flattening" 任何指针数据的效果,但不适用于循环数据结构。

(您可以编写自己的更简单的编码器,它在遇到指针时简单地跟随指针,否则像 %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}

我们现在有两个不同的实体,t1t2,它们都是 "contain as a value" {1 2}。在 Go 中,t1t2 是不同的,因为它们的指针不同。换句话说,他们的价值观是不同的。在提议的encoding中,t1t2都编码相同,所以它们是相同的值。

指针会出现这种情况:底层数据可能相同——某种意义上的 "same value"——但保存这些值的对象可能在位置上不同,因此如果一个对象是修改的,另一个不是。如果你 运行 这样的对象通过编码然后解码过程使它们 共享 指向 值,你可以给提高修改一个对象而不修改另一个对象或区分它们的能力。

既然你可以选择如何进行编码,就可以准确地决定你想在这里发生什么。但你必须有意识地做出这样的选择,而不是偶然。