| // Copyright 2017 The Wuffs Authors. |
| // |
| // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or |
| // https://www.apache.org/licenses/LICENSE-2.0> or the MIT license |
| // <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your |
| // option. This file may not be copied, modified, or distributed |
| // except according to those terms. |
| // |
| // SPDX-License-Identifier: Apache-2.0 OR MIT |
| |
| //go:build ignore |
| // +build ignore |
| |
| package main |
| |
| // checksum.go prints a checksum of stdin's bytes, or of the opening digits of |
| // π. Checksum algorithms include "adler32", "crc32/ieee" and "xxhash32". |
| // |
| // Usage: go run checksum.go -algorithm=crc32/ieee < foo.bar |
| |
| import ( |
| "crypto/sha256" |
| "flag" |
| "fmt" |
| "hash" |
| "hash/adler32" |
| "hash/crc32" |
| "hash/crc64" |
| "io" |
| "os" |
| "strings" |
| |
| "github.com/pierrec/xxHash/xxHash32" |
| "github.com/pierrec/xxHash/xxHash64" |
| ) |
| |
| var ( |
| algorithm = flag.String("algorithm", "adler32", "checksum algorithm") |
| count = flag.Int("count", 300, "number of cases (max 300), needs -pi flag") |
| pi = flag.Bool("pi", false, "checksum the digits of pi instead of stdin") |
| ) |
| |
| func main() { |
| if err := main1(); err != nil { |
| os.Stderr.WriteString(err.Error() + "\n") |
| os.Exit(1) |
| } |
| } |
| |
| func main1() error { |
| flag.Parse() |
| |
| if *pi { |
| const digits = "3." + |
| "141592653589793238462643383279502884197169399375105820974944592307816406" + |
| "286208998628034825342117067982148086513282306647093844609550582231725359" + |
| "408128481117450284102701938521105559644622948954930381964428810975665933" + |
| "446128475648233786783165271201909145648566923460348610454326648213393607" + |
| "260249141" |
| if len(digits) != 299 { |
| panic("bad len(digits)") |
| } else if (*count < 0) || (len(digits) < (*count - 1)) { |
| return fmt.Errorf("invalid count: %d", *count) |
| } |
| newLine := false |
| for i := 0; i < *count; i++ { |
| if err := do(strings.NewReader(digits[:i])); err != nil { |
| return err |
| } |
| fmt.Print(",") |
| newLine = i&7 == 7 |
| if newLine { |
| fmt.Println() |
| } |
| } |
| if !newLine { |
| fmt.Println() |
| } |
| |
| } else { |
| if err := do(os.Stdin); err != nil { |
| return err |
| } |
| fmt.Println() |
| } |
| return nil |
| } |
| |
| func do(r io.Reader) error { |
| h := io.Writer(nil) |
| switch *algorithm { |
| case "adler32": |
| h = adler32.New() |
| case "crc32/ieee": |
| h = crc32.NewIEEE() |
| case "crc64/ecma": |
| h = crc64.New(crc64.MakeTable(crc64.ECMA)) |
| case "sha256": |
| h = sha256.New() |
| case "xxhash32": |
| h = xxHash32.New(0) |
| case "xxhash64": |
| h = xxHash64.New(0) |
| default: |
| return fmt.Errorf("unknown algorithm %q", *algorithm) |
| } |
| |
| if _, err := io.Copy(h, r); err != nil { |
| return err |
| } |
| |
| switch h := h.(type) { |
| case hash.Hash32: |
| fmt.Printf("0x%08X", h.Sum32()) |
| case hash.Hash64: |
| fmt.Printf("0x%016X", h.Sum64()) |
| case hash.Hash: |
| b := h.Sum(nil) |
| for i, x := range b { |
| if i == 0 { |
| fmt.Printf("0x") |
| } else if (i & 7) == 0 { |
| fmt.Printf("_") |
| } |
| fmt.Printf("%02X", x) |
| } |
| default: |
| return fmt.Errorf("algorithm %q is not a Hash32 or Hash64", *algorithm) |
| } |
| return nil |
| } |