调用Write(val)和Sum(nil)和hash中的Sum(val)之间的差异?

调用Write(val)和Sum(nil)和hash中的Sum(val)之间的差异?,hash,go,Hash,Go,我正在研究使用Go的crypto包,我有一个简单的例子,我想弄清楚。我知道我可以对散列使用io.WriteString,但我想在将散列对象与另一个库接口之前直接理解它 package main import ( "crypto/md5" "fmt" ) func main() { val := []byte("Hello World") h := md5.New() h.Write(val) fmt.Printf("%x\n", h.Sum(

我正在研究使用Go的crypto包,我有一个简单的例子,我想弄清楚。我知道我可以对散列使用
io.WriteString
,但我想在将散列对象与另一个库接口之前直接理解它

package main

import (
    "crypto/md5"
    "fmt"
)

func main() {
    val := []byte("Hello World")

    h := md5.New()
    h.Write(val)
    fmt.Printf("%x\n", h.Sum(nil))

    fmt.Println()

    h2 := md5.New()
    fmt.Printf("%x\n", h2.Sum(val))
}
生成此输出:

b10a8db164e0754105b7a99be72e3fe5

48656c6c6f20576f726c64d41d8cd98f00b204e9800998ecf8427e
在伪代码中,我希望:

h.Write(part1)
h.Write(part2)
result := h.Sum(part3)
将产生与相同的结果

result := h.Sum(part1 + part2 + part3)
但在我上面的简单示例中,我甚至不能让一个部件在两种情况下产生相同的输出
Write
神秘地丢失了,这让我相信我可能用错了。我尤其感到困惑的是,如果我只使用
Sum
方法,我会得到比通常更长的散列

这是怎么回事

编辑:我决定打印
val
的十六进制,并注意到它与
h2.Sum(val)
输出的开头完全匹配。作为比较:

val: 48656c6c6f20576f726c64
 h2: 48656c6c6f20576f726c64d41d8cd98f00b204e9800998ecf8427e
我肯定做错了什么。我是否应该完全避免使用
Write
函数并坚持使用
io

将当前哈希值附加到参数并返回结果。参数未添加到哈希中

提供此参数是为了让应用程序在获取哈希时避免分配。许多应用程序不需要这种优化,只需调用
h.Sum(nil)

我明白了。如果我创建一个“空”md5对象并将其打印出来,我将得到h2的另一半。似乎我从其他语言中引入了太多的假设。Go最终会让我放弃那样做。