| // 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 | 
 | } |