Hash Golang md5 Sum()函数

Hash Golang md5 Sum()函数,hash,go,cryptography,md5,md5sum,Hash,Go,Cryptography,Md5,Md5sum,输出: package main import ( "crypto/md5" "fmt" ) func main() { hash := md5.New() b := []byte("test") fmt.Printf("%x\n", hash.Sum(b)) hash.Write(b) fmt.Printf("%x\n", hash.Sum(nil)) } 有人能给我解释一下为什么/如何得到两种打印的不同结果吗?来自文档: *md5

输出:

package main

import (
    "crypto/md5"
    "fmt"
)

func main() {
    hash := md5.New()
    b := []byte("test")
    fmt.Printf("%x\n", hash.Sum(b))
    hash.Write(b)
    fmt.Printf("%x\n", hash.Sum(nil))
}
有人能给我解释一下为什么/如何得到两种打印的不同结果吗?

来自文档:

*md5.digest74657374d41d8cd98f00b204e9800998ecf8427e
098f6bcd4621d373cade4e832627b4f6
所以“*74657374*d41d8cd98f00b204e9800998ecf8427e”实际上是“test”的十六进制表示,加上散列的初始状态

    // Sum appends the current hash to b and returns the resulting slice.
    // It does not change the underlying hash state.
    Sum(b []byte) []byte
将导致。。。"74657374"!


所以基本上,
hash.Sum(b)
并没有做你认为它做的事情。第二条语句是正确的散列

有两种方法可以实际获取字节片的大小:

fmt.Printf("%x", []byte{"test"})
根据,您的
hash.Sum(b)
就像调用
append(b,actual-hash-of-an-empty-md5-hash)

Sum
的定义:

func main() {
    hash := md5.New()
    b := []byte("test")
    hash.Write(b)
    fmt.Printf("way one : %x\n", hash.Sum(nil))
    fmt.Printf("way two : %x\n", md5.Sum(b))
}

当你调用
Sum(nil)
时,它直接以字节片的形式返回
d.checkSum()
,但是如果你调用
Sum([]字节)
时,它会将
d.checkSum()
附加到你的输入中。

我正在构建已经很好的答案。我不确定
Sum
是否真的是您想要的函数。从文件中:

func (d0 *digest) Sum(in []byte) []byte {
    // Make a copy of d0 so that caller can keep writing and summing.
    d := *d0
    hash := d.checkSum()
    return append(in, hash[:]...)
}
此函数有一个双重用例,您似乎以一种不幸的方式将其混合在一起。用例包括:

  • 计算单个运行的哈希值
  • 链接多个运行的输出
  • 如果您只是想计算某个内容的散列,请使用或

    根据上述文档摘录,此代码将
    数据的校验和附加到
    nil
    ,从而产生
    数据的校验和

    如果要链接多个哈希块(第二个用例是
    hash.Sum
    ),可以这样做:

    digest := md5.New()
    digest.Write(data)
    hash := digest.Sum(nil)
    
    这将把每个迭代的散列附加到已经计算的散列中。可能不是你想要的

    因此,现在您应该能够了解代码失败的原因。如果不是,则使用此注释版本的代码():

    hash:=md5.New()
    b:=[]字节(“测试”)
    fmt.Printf(“%x\n”,hash.Sum(b))//给出74657374(74657374=“test”)
    fmt.Printf(“%x\n”,hash.Sum([]字节(“AAA”))//给出414141(41='A'))
    fmt.Printf(“%x\n”,hash.Sum(nil))//作为append(nil,hash)=hash提供
    fmt.Printf(“%x\n”,hash.Sum(b))//给出74657374(74657374=“test”)
    fmt.Printf(“%x\n”,hash.Sum([]字节(“AAA”))//给出414141(41='A'))
    hash.Write(b)
    fmt.Printf(“%x\n”,hash.Sum(nil))//给出了一个完全不同的哈希值,因为内部字节因Write()而改变
    
    我想直截了当地告诉你:

    为什么/如何获得两种打印的不同结果

    答复:

    当您创建md5
    hash
    的新实例时,一旦调用
    hash.Sum(b)
    它实际上是
    b
    的md5 hash,因为
    hash
    本身是空的,因此您得到了
    74657374d41d8cd98f00b204e98ecf8427e
    作为输出

    现在,在下一条语句中,写入(b)
    您正在向哈希实例写入
    b
    ,然后调用
    hash.Sum(nil)
    它将计算您刚才写入的
    b
    的md5,并将其和上一个值相加,即
    74657374d41d8cd98f00b204e9800998ecf8427e

    这就是您获得这些输出的原因

    请参考
    Sum
    API:

    hash := md5.New()
    

    没有回答我为什么总和(零)是different@w00d据我所知,您的
    Sum(nil)
    返回不同结果的唯一原因是您事先调用了
    Write
    ,这让
    hash
    在下次调用
    checkSum()
    时生成另一个校验和。请参阅thank,但答案仍然模糊,因为空md5哈希的哈希没有那个数字。。Thank@nemo让我看得更清楚了,但仍然没有解释为什么打印出来的文本格式不同
    “%x”
    打印字节数组的十六进制表示,调用
    Sum(b)
    会在
    b
    的值后面附加一个“”的散列。感谢我现在清楚了Sum(b)返回的是什么,但仍然不清楚Sum(nil)返回的原因你得到了正确的答案吗?我可以从评论中看出你对结果不清楚??我有一个答案
    hashed := make([]byte, 0)
    for hasData {
        digest.Write(data)
        hashed = digest.Sum(hashed)
    }
    
    hash := md5.New()
    b := []byte("test")
    fmt.Printf("%x\n", hash.Sum(b))             // gives 74657374<hash> (74657374 = "test")
    fmt.Printf("%x\n", hash.Sum([]byte("AAA"))) // gives 414141<hash> (41 = 'A')
    fmt.Printf("%x\n", hash.Sum(nil))           // gives <hash> as append(nil, hash) == hash
    
    fmt.Printf("%x\n", hash.Sum(b))             // gives 74657374<hash> (74657374 = "test")
    fmt.Printf("%x\n", hash.Sum([]byte("AAA"))) // gives 414141<hash> (41 = 'A')
    hash.Write(b)
    fmt.Printf("%x\n", hash.Sum(nil))           // gives a completely different hash since internal bytes changed due to Write()
    
    hash := md5.New()
    
    func (d0 *digest) Sum(in []byte) []byte {
    85      // Make a copy of d0 so that caller can keep writing and summing.
    86      d := *d0
    87      hash := d.checkSum()
    88      return append(in, hash[:]...)
    89  }