commit adcd6e6480d94aeb428986d5a1ba99747f1d7b38 Author: Augusto Roman Date: Thu Sep 22 20:31:24 2016 -0700 Initial commit. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..944d605 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 Augusto Roman + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..7fceeb3 --- /dev/null +++ b/README.md @@ -0,0 +1,35 @@ +# CRC + +CRC is a simple command-line utility to compute various CRC values for one or +more files. + +It supports three CRC algorithms (selected via `--mode=`): +* `crc64-ecma` (*default*) uses the [ECMA polynomial](https://godoc.org/hash/crc64#pkg-constants) to compute a 64-bit CRC. +* `crc64-iso` uses the [ISO polynomial](https://godoc.org/hash/crc64#pkg-constants) to compute a 64-bit CRC. +* `crc32` uses the [IEEE polynomial](https://godoc.org/hash/crc32#pkg-constants) to compute a 32-bit CRC. This is equivalent to the `crc32` linux binary. + +If only a single file is specified on the command line, then only the hexadecimal hash is printed. If more than one file is specified, the output will be +``` + +``` +for each file. + +## Installation + +```bash +go get github.com/augustoroman/crc +``` + +## Usage + +```bash +# Compute the default hash (crc64 w/ ECMA polynomial) of one or more files. +crc [ ...] +# Compute the crc64 hash with ISO polynomial. +crc --mode=crc64-iso [ ...] +# Compute the crc32 hash (with the IEEE polynomial). +crc --mode=crc32 [ ...] +``` + +## License +This is released under the MIT license diff --git a/main.go b/main.go new file mode 100644 index 0000000..dcb2451 --- /dev/null +++ b/main.go @@ -0,0 +1,71 @@ +// 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" + "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=] 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 { + fmt.Printf("%0*x\n", hasher.Size(), hasher.Sum(nil)) + } else { + fmt.Printf("%0*x\t%s\n", hasher.Size(), hasher.Sum(nil), filename) + } + } + 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) + } +}