blob: c9df7695bfb522cd2d65270ca110c0cf493e5323 [file] [log] [blame]
Nigel Taode606102019-10-26 08:09:18 +11001// Copyright 2019 The Wuffs Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Nigel Tao788479d2021-08-22 10:52:51 +100015//go:build ignore
Nigel Taode606102019-10-26 08:09:18 +110016// +build ignore
17
18package main
19
20// print-byte-frequencies.go prints the relative frequencies of stdin's bytes.
21//
22// Usage: go run print-byte-frequencies.go < foo.bin
23
24import (
25 "flag"
26 "fmt"
27 "io"
28 "os"
29)
30
31var (
32 showZeroes = flag.Bool("show-zeroes", false, "whether to print zero-frequency bytes")
33)
34
35func main() {
36 if err := main1(); err != nil {
37 os.Stderr.WriteString(err.Error() + "\n")
38 os.Exit(1)
39 }
40}
41
42func main1() (retErr error) {
43 flag.Parse()
44 os.Stdout.WriteString("byte count / total = frequency heat\n")
45
46 in := make([]byte, 4096)
47 counts := [256]uint64{}
48 total := uint64(0)
49 for {
50 n, err := os.Stdin.Read(in)
51 for _, x := range in[:n] {
52 counts[x]++
53 }
54 total += uint64(n)
55 if err != nil {
56 if err != io.EOF {
57 retErr = err
58 }
59 break
60 }
61 }
62
63 for c, count := range counts {
64 if (count == 0) && !*showZeroes {
65 continue
66 }
67 freq := float64(0)
68 if total > 0 {
69 freq = float64(count) / float64(total)
70 }
71 fmt.Printf("0x%02X %c %12d / %12d = %.08f %s\n",
72 c, printable(c), count, total, freq, heat(freq))
73 }
74
75 return retErr
76}
77
78func printable(c int) rune {
79 if (0x20 <= c) && (c < 0x7F) {
80 return rune(c)
81 }
82 return '.'
83}
84
85func heat(f float64) string {
86 const s = "++++++++"
87 i := int(f * 256)
88 for n, threshold := len(s), 128; n > 0; n, threshold = n-1, threshold>>1 {
89 if i >= threshold {
90 return s[:n]
91 }
92 }
93 return ""
94}