go - 对为什么 hashsum、encode、print 与 Go 中的 write、hashum、encode、print 不同感到困惑?
问题描述
对不起标题。我想不出更好的方式来表达我的问题,如果其他人可以的话,我会很高兴地改变它。
哈希器定义为
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()
不会散列传递的切片。传递的切片用作目标:它将当前哈希附加到它,并且不会更改底层哈希状态。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上尝试一下。
推荐阅读
- javascript - 如何在正确反应中添加列表项
- c - 如何修复我的井字游戏代码,它只打印棋盘的顶行?
- javascript - 为什么当内部订阅发生变化时,外部订阅范围内的变量集会发生变化
- javascript - SVG矩形的一致填充
- git - 使用子模块镜像 Eclipse 平台聚合器存储库
- lua - 是否可以同时更改多个值,不同的数量?
- javascript - 如何从动态列表中的特定对象更新特定字段?
- vb.net - 带有 UIDS 的 POP3 GetMessages
- shell - 如何平均不同文件的值并将它们保存在新文件中
- django - Django 使用 Case & When (条件表达式)注释排除