Skip to content

Instantly share code, notes, and snippets.

@phrozen
Created June 11, 2011 00:03
Show Gist options
  • Save phrozen/1020054 to your computer and use it in GitHub Desktop.
Save phrozen/1020054 to your computer and use it in GitHub Desktop.
Simple utility to obtain multiple hashes of a file from the command line.
/*
Hash - Guillermo Estrada
Marko Mikulicic
Kyle Lemons
Simple utility to obtain the MD5 and/or SHA-1
of a file from the command line.
2011
*/
package main
// Typically, imports are sorted in alphabetical order
import (
"crypto/md5"
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"crypto/ripemd160"
"flag"
"fmt"
"hash"
"io"
"os"
)
func main() {
// Instead of defining each flag, drying up code
algos := [...]string{"md5", "sha1", "sha256", "sha512", "ripemd160"}
impls := [...]hash.Hash{md5.New(), sha1.New(), sha256.New(), sha512.New(), ripemd160.New()}
flags := make([]*bool, len(algos))
for i, a := range algos {
flags[i] = flag.Bool(a, false, fmt.Sprintf("-%s calculate %s hash of file", a, a))
}
flag.Parse()
// Blocks of var/const work just as well inside a function call
var (
writers []io.Writer
hashes []hash.Hash
names []string
)
// Closures can be used to collect common operations into a nice, clean function call
push := func(name string, h hash.Hash) {
writers = append(writers, h) // a Hash is a writer, so this is easy
hashes = append(hashes, h)
names = append(names, name)
}
// Now any number of hashes can be added here with very little code
for i, flag := range flags {
if *flag {
push(algos[i],impls[i])
}
}
if len(names) == 0 {
flag.Usage()
os.Exit(1)
}
in, err := os.Open(flag.Arg(0))
if err != nil {
fmt.Println(err)
os.Exit(1)
}
// The variadic expansion of a slice is really convenient.
io.Copy(io.MultiWriter(writers...), in)
for i, name := range names {
fmt.Printf("%9s: %x\n", name, hashes[i].Sum())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment