md5.Sum() and md5.New().Sum() not match

403 views
Skip to first unread message

Terry Wu

unread,
Oct 24, 2015, 2:28:20 PM10/24/15
to golang-nuts
See : http://play.golang.org/p/SnTt2BxHQe

package main


import (
 
"crypto/md5"
 
"fmt"
)


func main
() {
 h
:= md5.New()
 fmt
.Printf("%x\n%x\n", h.Sum([]byte("abc")), md5.Sum([]byte("abc")))
}

OUTPUT:

616263d41d8cd98f00b204e9800998ecf8427e
900150983cd24fb0d6963f7d28e17f72


is it suppose to be like this? why ?

Ian Lance Taylor

unread,
Oct 24, 2015, 2:45:16 PM10/24/15
to Terry Wu, golang-nuts
When you call md5.New you get a value that implements the Hash
interface (https://golang.org/pkg/hash/#Hash). See the description of
the Sum method of the Hash interface. It's quite different from what
md5.Sum does. In particular note that the output of h.sum starts with
616263, which is the ASCII hex code for "abc".

Ian

Manlio Perillo

unread,
Oct 24, 2015, 2:48:46 PM10/24/15
to golang-nuts
This is what you are doing:

fmt.Printf("%x\n%x%x\n", h.Sum([]byte("abc")), []byte("abc"), md5.Sum([]byte("")))

You are appending the md5 hash of the empty string, to the string "abc".
Read the documentation.


Regards  Manlio 

dja...@gmail.com

unread,
Oct 24, 2015, 8:21:10 PM10/24/15
to golang-nuts

Peter Waller

unread,
Oct 26, 2015, 9:05:43 AM10/26/15
to Ian Lance Taylor, Terry Wu, golang-nuts
I'm thankful that I don't think I happen to have made this mistake in production code - out of habit I only ever wrote .Sum(nil).

I'm very surprised to hear this is the case, especially since the Hash documentation says that .Size() returns the number of bytes that .Sum() will return, implying that the number of bytes returned by .Sum() is a constant.

Can anyone explain why I might want this surprising behaviour where Sum(x) prepends bytes x to the hash?

(Obviously, I'm aware this isn't going to change. I'm asking so that I can hang more baubles from my tree of knowledge; not make this mistake in the future and correct other people who might otherwise make the mistake).


--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

James Bardin

unread,
Oct 26, 2015, 11:25:34 AM10/26/15
to golang-nuts, ia...@golang.org, terry...@gmail.com


On Monday, October 26, 2015 at 9:05:43 AM UTC-4, Peter Waller wrote:
I'm thankful that I don't think I happen to have made this mistake in production code - out of habit I only ever wrote .Sum(nil).

I'm very surprised to hear this is the case, especially since the Hash documentation says that .Size() returns the number of bytes that .Sum() will return, implying that the number of bytes returned by .Sum() is a constant.

Can anyone explain why I might want this surprising behaviour where Sum(x) prepends bytes x to the hash?


The most useful feature isn't that Sum prepends the bytes from x, it's that Sum "appends" the output to x. Normally you still pass in a zero length slice. This lets you use (and reuse) a preallocated slice for the output, so that Sum doesn't need do any other allocations.

Peter Waller

unread,
Oct 26, 2015, 11:33:13 AM10/26/15
to James Bardin, golang-nuts, Ian Lance Taylor, Terry Wu
On 26 October 2015 at 15:25, James Bardin <j.ba...@gmail.com> wrote:
The most useful feature isn't that Sum prepends the bytes from x, it's that Sum "appends" the output to x. Normally you still pass in a zero length slice. This lets you use (and reuse) a preallocated slice for the output, so that Sum doesn't need do any other allocations.

Aha. That makes sense. I wasn't thinking with my zero-allocations hat on.
Reply all
Reply to author
Forward
0 new messages