2016-09-22 20:31:24 -07:00
|
|
|
// CRC is a simple command-line utility to compute CRC values for one or more files.
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"flag"
|
|
|
|
"fmt"
|
|
|
|
"hash"
|
|
|
|
"hash/crc32"
|
|
|
|
"hash/crc64"
|
2018-02-24 13:51:17 -08:00
|
|
|
"encoding/binary"
|
2016-09-22 20:31:24 -07:00
|
|
|
"io"
|
|
|
|
"os"
|
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
mode := flag.String("mode", "crc64-ecma",
|
|
|
|
"CRC method to use. Valid values are 'crc32' (IEEE), 'crc64-iso', and 'crc64-ecma'")
|
|
|
|
flag.Usage = func() {
|
|
|
|
fmt.Fprintf(os.Stderr, "Usage: %s [-mode=<MODE>] file [file ...]\n", os.Args[0])
|
|
|
|
flag.PrintDefaults()
|
|
|
|
}
|
|
|
|
flag.Parse()
|
|
|
|
|
|
|
|
hasher, err := NewHasher(*mode)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Fprintln(os.Stderr, err)
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
|
|
|
|
if flag.NArg() == 0 {
|
|
|
|
fmt.Fprintf(os.Stderr, "Specify one or more filenames to checksum.\n")
|
|
|
|
os.Exit(2)
|
|
|
|
}
|
|
|
|
|
|
|
|
exitCode := 0
|
|
|
|
for _, filename := range flag.Args() {
|
|
|
|
hasher, _ = NewHasher(*mode)
|
|
|
|
f, err := os.Open(filename)
|
|
|
|
if err != nil {
|
|
|
|
exitCode = 3
|
|
|
|
fmt.Fprintf(os.Stderr, "Cannot open %q: %v\n", filename, err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
_, err = io.Copy(hasher, f)
|
|
|
|
f.Close()
|
|
|
|
if err != nil {
|
|
|
|
exitCode = 3
|
|
|
|
fmt.Fprintf(os.Stderr, "Error reading %q: %v\n", filename, err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
if flag.NArg() == 1 {
|
2018-02-24 13:51:17 -08:00
|
|
|
fmt.Printf("%0*d\n", hasher.Size(), binary.BigEndian.Uint32(hasher.Sum(nil)))
|
2016-09-22 20:31:24 -07:00
|
|
|
} else {
|
2018-02-24 13:51:17 -08:00
|
|
|
fmt.Printf("%0*d\t%s\n", hasher.Size(), binary.BigEndian.Uint32(hasher.Sum(nil)), filename)
|
2016-09-22 20:31:24 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
os.Exit(exitCode)
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewHasher(mode string) (hash.Hash, error) {
|
|
|
|
switch mode {
|
|
|
|
case "crc32", "crc32-ieee":
|
|
|
|
return crc32.NewIEEE(), nil
|
|
|
|
case "crc64-iso":
|
|
|
|
return crc64.New(crc64.MakeTable(crc64.ISO)), nil
|
|
|
|
case "crc64-ecma":
|
|
|
|
return crc64.New(crc64.MakeTable(crc64.ECMA)), nil
|
|
|
|
default:
|
|
|
|
return nil, fmt.Errorf("ERROR: Invalid mode %q", mode)
|
|
|
|
}
|
|
|
|
}
|