It got me there: https://www.socketloop.com/tutorials/how-to-generate-checksum-for-file-in-go. After reading I was surprise that Go doesn't have ReaderWriter which reads data from some object implementing
io.Reader
and writes data to some other
object implementing io.Writer
. I've grabbed the code
and started cleaning it but keeping all file content in memory made me search.
I went to GoLang official doc and found:
func Copy(dst Writer, src Reader) (written int64, err error)
Copy copies from src to dst until either EOF is reached on src or an error occurs.
To summarize:
- Go defines interface
hash.Hash
which is implemented in packages:crypto/hmac
,crypto/md5
,crypto/sha1
,crypto/sha256
,crypto/sha512
. - hash.Hash inherits io.Writer, this mean it has Write method.
- One should use io.Copy to copy data between reader and writer.
Below is the full source of
main.go
:
package main import ( "crypto/md5" "fmt" "io" "os" ) func ComputeMd5(filePath string) ([]byte, error) { var result []byte file, err := os.Open(filePath) if err != nil { return result, err } defer file.Close() hash := md5.New() if _, err := io.Copy(hash, file); err != nil { return result, err } return hash.Sum(result), nil } func main() { if b, err := ComputeMd5("main.go"); err != nil { fmt.Printf("Err: %v", err) } else { fmt.Printf("main.go md5 checksum is: %x", b) } }
$ go run main.go main.go md5 checksum is: facd74ec8975d8fd84897fb352f8f87e
Superb..
ReplyDeleteThank u....U saved my time
Thanks for this. I'm quite new to Go so what I'm about to say may be completely wrong…
ReplyDeleteI'm a little bit confused about how `result` gets passed into `hash.Sum` at the end.
At this point as `hash` has already been passed the entire contents of the file by `io.Copy` and `result` is empty (it never gets set to anything) I _think_ passing `result` into `hash.Sum` doesn't do anything.
I think it might be a tiny bit clearer to change the return statement to be:-
```
return hash.Sum(nil), nil
```
… which seems to work OK …
https://gist.github.com/matthew-andrews/527f4b73a85f2ee7515668c54432c16f#file-main-go-L26
Matt
https://mattandre.ws
Thanks man!
ReplyDeleteDear Pawel, thanks for posting this snippet. Go's hashing API is a bit of misleading, I couldn't figure out how to count hash from chunk stream on my own.
ReplyDelete