Golang md5 Sum()函数

 包主程序

import(
“ crypto / md5”
“ fmt”

func main(){
hash:= md5.New()
b:= [] byte(“ test”)
fmt.Printf(“%x
”,hash.Sum(b) )
hash.Write(b)
fmt.Printf(“%x
”,hash.Sum(nil))
}
</ code> </ pre>

输出 :</ p>

  * md5.digest74657374d41d8cd98f00b204e9800998ecf8427e 
098f6bcd4621d373cade4e832627b4f6
</ code> </ pre>

请有人向我解释为什么/如何获得 两次打印的结果不同?</ p>
</ div>

展开原文

原文

package main

import (
    "crypto/md5"
    "fmt"
)

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

Output:

*md5.digest74657374d41d8cd98f00b204e9800998ecf8427e
098f6bcd4621d373cade4e832627b4f6

Could someone please explain to me why/how do I get different result for the two print ?

dongzang7182
dongzang7182 您是否有正确的答案,我可以在评论中看到您不清楚结果吗?我对此有一个答案
3 年多之前 回复
douchui4459
douchui4459 下选民可以解释他的行为吗?
6 年多之前 回复

4个回答

I'm building up on the already good answers. I'm not sure if Sum is actually the function you want. From the hash.Hash documentation:

// Sum appends the current hash to b and returns the resulting slice.
// It does not change the underlying hash state.
Sum(b []byte) []byte

This function has a dual use-case, which you seem to mix in an unfortunate way. The use-cases are:

  1. Computing the hash of a single run
  2. Chaining the output of several runs

In case you simply want to compute the hash of something, either use md5.Sum(data) or

digest := md5.New()
digest.Write(data)
hash := digest.Sum(nil)

This code will, according to the excerpt of the documentation above, append the checksum of data to nil, resulting in the checksum of data.

If you want to chain several blocks of hashes, the second use-case of hash.Sum, you can do it like this:

hashed := make([]byte, 0)
for hasData {
    digest.Write(data)
    hashed = digest.Sum(hashed)
}

This will append each iteration's hash to the already computed hashes. Probably not what you want.

So, now you should be able to see why your code is failing. If not, take this commented version of your code (On play):

hash := md5.New()
b := []byte("test")
fmt.Printf("%x
", hash.Sum(b))             // gives 74657374<hash> (74657374 = "test")
fmt.Printf("%x
", hash.Sum([]byte("AAA"))) // gives 414141<hash> (41 = 'A')
fmt.Printf("%x
", hash.Sum(nil))           // gives <hash> as append(nil, hash) == hash

fmt.Printf("%x
", hash.Sum(b))             // gives 74657374<hash> (74657374 = "test")
fmt.Printf("%x
", hash.Sum([]byte("AAA"))) // gives 414141<hash> (41 = 'A')
hash.Write(b)
fmt.Printf("%x
", hash.Sum(nil))           // gives a completely different hash since internal bytes changed due to Write()
douzou0073
douzou0073 很好的解释。
6 年多之前 回复



您有2种方法实际获得 md5.Sum </ code> 字节片:</ p>

  func main(){
hash: = md5.New()
b:= [] byte(“ test”)
hash.Write(b)
fmt.Printf(“方式一:%x
”,hash.Sum(nil))\ n fmt.Printf(“第二种方式:%x
”,md5.Sum(b))
}
</ code> </ pre>

根据 http://golang.org/src/pkg/crypto/md5/md5.go#L88 </ a>,您的 hash.Sum(b)</ code>就像调用 append(b,real-hash-of-an-empty-md5-hash)</ code>。</ p>

Sum </ code>的定义:</ p>

  func(d0 * digest)Sum(以[] byte为单位)[] byte {

//复制d0,以便调用者可以继续写和求和。
d:= * d0
hash:= d.checkSum()
返回append(in,hash [:] ...)\ n}
</ code> </ pre>

调用 Sum(nil)</ code>时,它将返回 d.checkSum()</ c ode>直接作为字节切片,但是,如果调用 Sum([] byte)</ code>,则会将 d.checkSum()</ code>附加到输入中。</ p>
< / DIV>

展开原文

原文

You have 2 ways to actually get a md5.Sum of a byte slice :

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

According to http://golang.org/src/pkg/crypto/md5/md5.go#L88, your hash.Sum(b) is like calling append(b, actual-hash-of-an-empty-md5-hash).

The definition of 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[:]...)
}

When you call Sum(nil) it returns d.checkSum() directly as a byte slice, however if you call Sum([]byte) it appends d.checkSum() to your input.

doumian3780
doumian3780 “%x”打印一个字节数组的十六进制表示形式,调用Sum(b)会将“”的哈希值附加到b的值上。
6 年多之前 回复
dp13668681869
dp13668681869 谢谢,但是答案仍然很模糊,因为一个空的md5哈希的哈希没有那个数字..谢谢@nemo使我更清楚,但是仍然不能解释为什么打印出来的文本格式不同
6 年多之前 回复
douyangcheng4965
douyangcheng4965 据我所知,您的Sum(nil)返回不同的唯一原因是您事先调用了Write,这使哈希在下次调用checkSum()时产生另一个校验和。 参见play.golang.org/p/8yvaj7MvLB
6 年多之前 回复
dqotv26286
dqotv26286 检查编辑。
6 年多之前 回复
duanlinghe8417
duanlinghe8417 没有回答我为什么Sum(nil)不同
6 年多之前 回复



从文档中获取:</ p>

  // Sum将当前哈希附加到b和 返回结果切片。
//不更改基础哈希状态。
Sum(b [] byte)[] byte
</ code> </ pre>

so“ * 74657374 * d41d8cd98f00b204e9800998ecf8427e”实际上是“测试”的十六进制表示形式,加上哈希的初始状态。</ p>

  fmt.Printf(“%x”,[] byte {“ 测试“})
</ code> </ pre>

将导致...” 74657374“!</ p>

因此基本上是 hash.Sum (b)</ code>没有按照您的想法去做。 第二条语句是正确的哈希。 </ p>
</ div>

展开原文

原文

From the docs:

    // Sum appends the current hash to b and returns the resulting slice.
    // It does not change the underlying hash state.
    Sum(b []byte) []byte

so "*74657374*d41d8cd98f00b204e9800998ecf8427e" is actually a hex representation of "test", plus the initial state of the hash.

fmt.Printf("%x", []byte{"test"})

will result in... "74657374"!

So basically hash.Sum(b) is not doing what you think it does. The second statement is the right hash.

douya6606
douya6606 谢谢,现在我很清楚Sum(b)返回什么,但仍不清楚为什么Sum(nil)不同
6 年多之前 回复



我想告诉您这一点:</ p>


为什么/ 如何为两次打印得到不同的结果?</ p>
</ blockquote>

Ans:</ p>

  hash:= md5.New  ()
</ code> </ pre>

当您调用 hash.Sum(b)创建新的md5 hash </ code>实例时, code>它实际上是 b </ code>的md5哈希,因为 hash </ code>本身是空的,因此您得到了 74657374d41d8cd98f00b204e9800998ecf8427e </ code>作为输出。</ p>

现在在下一个语句 hash.Write(b)</ code>中,您将 b </ code>写入哈希实例,然后调用 hash.Sum(nil)</ code> 它将为您刚刚编写的 b </ code>计算md5,并将其求和为先前的值,即 74657374d41d8cd98f00b204e9800998ecf8427e </ code> </ p>

这些输出。</ p>

供参考,请查看 Sum </ code> API:</ p>

  func(d0 *摘要) 总和(以[]字节为单位)[]字节{
85 //复制d0,以便调用者可以继续写和求和。
86 d:= * d0
87 hash:= d.checkSum()
88返回append(in,hash [:] ...)
89 }
</ code> </ pre>
</ div>

展开原文

原文

I would like to tell you to the point:

why/how do I get different result for the two print ?

Ans:

hash := md5.New()

As you are creating a new instance of md5 hash once you call hash.Sum(b) it actually md5 hash for b as hash itself is empty, hence you got 74657374d41d8cd98f00b204e9800998ecf8427e as output.

Now in next statement hash.Write(b) you are writing b to the hash instance then calling hash.Sum(nil) it will calculate md5 for b that you just written and sum it to previous value i.e 74657374d41d8cd98f00b204e9800998ecf8427e

This is the reason you are getting these outputs.

For your reference look at the Sum API:

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  }

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐