1// 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 15// +build ignore 16 17package main 18 19// print-byte-frequencies.go prints the relative frequencies of stdin's bytes. 20// 21// Usage: go run print-byte-frequencies.go < foo.bin 22 23import ( 24 "flag" 25 "fmt" 26 "io" 27 "os" 28) 29 30var ( 31 showZeroes = flag.Bool("show-zeroes", false, "whether to print zero-frequency bytes") 32) 33 34func main() { 35 if err := main1(); err != nil { 36 os.Stderr.WriteString(err.Error() + "\n") 37 os.Exit(1) 38 } 39} 40 41func main1() (retErr error) { 42 flag.Parse() 43 os.Stdout.WriteString("byte count / total = frequency heat\n") 44 45 in := make([]byte, 4096) 46 counts := [256]uint64{} 47 total := uint64(0) 48 for { 49 n, err := os.Stdin.Read(in) 50 for _, x := range in[:n] { 51 counts[x]++ 52 } 53 total += uint64(n) 54 if err != nil { 55 if err != io.EOF { 56 retErr = err 57 } 58 break 59 } 60 } 61 62 for c, count := range counts { 63 if (count == 0) && !*showZeroes { 64 continue 65 } 66 freq := float64(0) 67 if total > 0 { 68 freq = float64(count) / float64(total) 69 } 70 fmt.Printf("0x%02X %c %12d / %12d = %.08f %s\n", 71 c, printable(c), count, total, freq, heat(freq)) 72 } 73 74 return retErr 75} 76 77func printable(c int) rune { 78 if (0x20 <= c) && (c < 0x7F) { 79 return rune(c) 80 } 81 return '.' 82} 83 84func heat(f float64) string { 85 const s = "++++++++" 86 i := int(f * 256) 87 for n, threshold := len(s), 128; n > 0; n, threshold = n-1, threshold>>1 { 88 if i >= threshold { 89 return s[:n] 90 } 91 } 92 return "" 93} 94