对为什么在 Go 中 hashsum、encode、print 与 write、hashum、encode、print 不同感到困惑?
Confused about why hashsum, encode, print is different then write, hashum, encode, print in Go?
对不起标题。我想不出更好的方式来表达我的问题,如果其他人可以的话,我会很高兴地改变它。
Hasher 定义为
hasher := md5.New()
无论如何,我很好奇为什么会这样:
fmt.Println(hex.EncodeToString(hasher.Sum([]byte(input))))
给我 6869d41d8cd98f00b204e9800998ecf8427e,而这个:
hasher.Write([]byte(input))
fmt.Println(hex.EncodeToString(hasher.Sum(nil))
给我 49f68a5c8493ec2c0bf489821c21fc3b
还有这个:
fmt.Printf("%x\n", md5.Sum([]byte(input)))
给我 49f68a5c8493ec2c0bf489821c21fc3b。
通常hasher.Sum()
不会散列传递的切片。传递的切片用作 destination:它将当前散列附加到它并且不更改底层散列状态。 hasher.Write()
显然在哈希计算中包含了传递的切片。这两个例子根本不同,不同的结果不过是意料之中的。
始终阅读文档。 hash.Hash.Sum()
:
// Sum appends the current hash to b and returns the resulting slice.
// It does not change the underlying hash state.
Sum(b []byte) []byte
因此,当您第一次调用 hasher.Sum()
时,无论您传递给它什么,就结果哈希而言都无关紧要。如果您之前没有向 hasher
写入任何内容,您将看到初始哈希值。
当您下次调用 hasher.Write([]byte(input))
时,您会将 input
的字节写入哈希器,因此当您接下来调用 hasher.Sum(nil)
时,您将看到计算的哈希值input
。由于您传递 nil
,因此将分配一个新的切片来容纳结果。
当您再次调用 hasher.Write([]byte(input))
时,如前所述:这不会改变散列状态,传递的切片不用作输入,而仅用作“返回”结果的目的地,当前哈希值。因此,您将获得与从之前的 hasher.Sum(nil)
调用中获得的哈希值相同的哈希值。显然,如果传递的切片没有足够的容量来存储结果,则会分配/使用一个新的。
查看这个完整的、可运行的示例,它可以重现您的输出:
input := "hi"
hasher := md5.New()
fmt.Println(hex.EncodeToString(hasher.Sum([]byte(input))))
hasher.Write([]byte(input))
fmt.Println(hex.EncodeToString(hasher.Sum(nil)))
fmt.Printf("%x\n", md5.Sum([]byte(input)))
在 Go Playground 上试试。
对不起标题。我想不出更好的方式来表达我的问题,如果其他人可以的话,我会很高兴地改变它。
Hasher 定义为
hasher := md5.New()
无论如何,我很好奇为什么会这样:
fmt.Println(hex.EncodeToString(hasher.Sum([]byte(input))))
给我 6869d41d8cd98f00b204e9800998ecf8427e,而这个:
hasher.Write([]byte(input))
fmt.Println(hex.EncodeToString(hasher.Sum(nil))
给我 49f68a5c8493ec2c0bf489821c21fc3b 还有这个:
fmt.Printf("%x\n", md5.Sum([]byte(input)))
给我 49f68a5c8493ec2c0bf489821c21fc3b。
通常hasher.Sum()
不会散列传递的切片。传递的切片用作 destination:它将当前散列附加到它并且不更改底层散列状态。 hasher.Write()
显然在哈希计算中包含了传递的切片。这两个例子根本不同,不同的结果不过是意料之中的。
始终阅读文档。 hash.Hash.Sum()
:
// Sum appends the current hash to b and returns the resulting slice. // It does not change the underlying hash state. Sum(b []byte) []byte
因此,当您第一次调用 hasher.Sum()
时,无论您传递给它什么,就结果哈希而言都无关紧要。如果您之前没有向 hasher
写入任何内容,您将看到初始哈希值。
当您下次调用 hasher.Write([]byte(input))
时,您会将 input
的字节写入哈希器,因此当您接下来调用 hasher.Sum(nil)
时,您将看到计算的哈希值input
。由于您传递 nil
,因此将分配一个新的切片来容纳结果。
当您再次调用 hasher.Write([]byte(input))
时,如前所述:这不会改变散列状态,传递的切片不用作输入,而仅用作“返回”结果的目的地,当前哈希值。因此,您将获得与从之前的 hasher.Sum(nil)
调用中获得的哈希值相同的哈希值。显然,如果传递的切片没有足够的容量来存储结果,则会分配/使用一个新的。
查看这个完整的、可运行的示例,它可以重现您的输出:
input := "hi"
hasher := md5.New()
fmt.Println(hex.EncodeToString(hasher.Sum([]byte(input))))
hasher.Write([]byte(input))
fmt.Println(hex.EncodeToString(hasher.Sum(nil)))
fmt.Printf("%x\n", md5.Sum([]byte(input)))
在 Go Playground 上试试。