initial commit
Signed-off-by: Vincent Batts <vbatts@hashbangbash.com>
This commit is contained in:
commit
058d5137d3
1 changed files with 106 additions and 0 deletions
106
main.go
Normal file
106
main.go
Normal file
|
@ -0,0 +1,106 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"sort"
|
||||
)
|
||||
|
||||
var (
|
||||
flTop = flag.Int("top", 1000, "top-end of the iteration")
|
||||
flCompress = flag.Bool("compress", false, "attempt to compress the rand data")
|
||||
flCSV = flag.Bool("csv", false, "output in csv format")
|
||||
)
|
||||
|
||||
const (
|
||||
c = 10
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
var fh *os.File
|
||||
if *flCompress {
|
||||
var err error
|
||||
fh, err = ioutil.TempFile("", "trie.things.")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer os.Remove(fh.Name())
|
||||
}
|
||||
|
||||
d := map[byte]*ByteCount{} // dictionary of byte counts
|
||||
b := make([]byte, c)
|
||||
for i := 0; i < *flTop; i++ {
|
||||
if _, err := rand.Read(b); err != nil {
|
||||
log.Fatalf("error:", err)
|
||||
}
|
||||
for j := 0; j < c; j++ {
|
||||
if _, ok := d[b[j]]; ok {
|
||||
d[b[j]].C++
|
||||
} else {
|
||||
d[b[j]] = &ByteCount{
|
||||
B: b[j],
|
||||
C: 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
if *flCompress {
|
||||
// write the bytes to tmpfile for comparison and compression
|
||||
if _, err := fh.Write(b); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
l := make([]*ByteCount, len(d))
|
||||
i := 0
|
||||
for _, v := range d {
|
||||
l[i] = v
|
||||
i++
|
||||
}
|
||||
// now sort by descending frequency ...
|
||||
sort.Sort(sort.Reverse(ByCount(l)))
|
||||
if *flCSV {
|
||||
// print a CSV for comparison/graphing
|
||||
fmt.Printf("byte,byte_hex,frequency\n")
|
||||
for i := range l {
|
||||
fmt.Printf("%d,%2.2x,%d\n", l[i].B, l[i].B, l[i].C)
|
||||
}
|
||||
} else {
|
||||
// print stats
|
||||
lLen := len(l)
|
||||
fmt.Printf("Length: %d\n", lLen)
|
||||
fmt.Printf("bytes counted: %d\n", *flTop*c)
|
||||
spread := (l[0].C - l[lLen-1].C)
|
||||
fmt.Printf("Freq Spread: %d\n", spread)
|
||||
fmt.Printf("Spread ratio: %.4f\n", 100*float64(spread)/float64(*flTop*c))
|
||||
fmt.Printf("Freq Max: %d\n", l[0].C)
|
||||
fmt.Printf("Freq Min: %d\n", l[lLen-1].C)
|
||||
fmt.Printf("Max 3 bytes: %2.2x(%d) %2.2x(%d) %2.2x(%d)\n", l[0].B, l[0].C, l[1].B, l[1].C, l[2].B, l[2].C)
|
||||
fmt.Printf("Min 3 bytes: %2.2x(%d) %2.2x(%d) %2.2x(%d)\n", l[lLen-1].B, l[lLen-1].C, l[lLen-2].B, l[lLen-2].C, l[lLen-3].B, l[lLen-3].C)
|
||||
}
|
||||
|
||||
// and produce a right leaning trie
|
||||
}
|
||||
|
||||
type ByteCount struct {
|
||||
B byte
|
||||
C int64
|
||||
}
|
||||
|
||||
type ByByte []*ByteCount
|
||||
|
||||
func (a ByByte) Len() int { return len(a) }
|
||||
func (a ByByte) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
func (a ByByte) Less(i, j int) bool { return a[i].B < a[j].B }
|
||||
|
||||
type ByCount []*ByteCount
|
||||
|
||||
func (a ByCount) Len() int { return len(a) }
|
||||
func (a ByCount) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
func (a ByCount) Less(i, j int) bool { return a[i].C < a[j].C }
|
Loading…
Reference in a new issue