blob: 1f4c3f7cefe3e8d41f0e4712e0b5327c89c5ad2e [file] [log] [blame]
// 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
}