Sunday, November 16, 2014

Google: "GoLang compute md5 of file"

Title of this post is my last Google query.
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:

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

4 comments:

  1. Superb..
    Thank u....U saved my time

    ReplyDelete
  2. Thanks for this. I'm quite new to Go so what I'm about to say may be completely wrong…

    I'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

    ReplyDelete
  3. Dear 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