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.Hashwhich 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