3 proc test {name format value min max} {
5 puts -nonewline "[format %20s $name]: [format $format $value]\
6 (<[format $format $min] and >[format $format $max]) "
7 if {$value > $min && $value < $max} {
16 puts stderr "Usage $argv0 filename\n\
17 \twhere filename file with at least 20000 random bits (i.e. /dev/random)"
20 fconfigure stderr -buffering none
21 set f [open [lindex $argv 0]]
22 fconfigure $f -translation binary -blocking y
23 puts -nonewline stderr "Reading 20000 bits"
24 set bytes [read $f 2500]
27 if {[string length $bytes]<2500} {
28 puts stderr "Need at least 2500 bytes, got [string length $bytes]"
33 array set hex2ones {0 0 1 1 2 1 3 2 4 1 5 2 6 2 7 3 8 1 9 2 a 2 b 3 c 2
36 binary scan $bytes H* hex
39 array set hist {0 0 1 0 2 0 3 0 4 0 5 0 6 0 7 0 8 0 9 0 a 0 b 0 c 0 d 0 e 0 f 0}
41 foreach nibble [split $hex ""] {
45 foreach {nibble count} [array get hist] {
46 set sumsquare [expr {$sumsquare + $count * $count}]
47 incr ones [expr $hist($nibble)*$hex2ones($nibble)]
51 test "Monobit test" "%5d" $ones 9654 10346
53 set chi [expr {$sumsquare*16.0/5000-5000}]
55 test "Poker test" %5.2f $chi 1.03 57.4
56 binary scan $bytes b* bits
59 array set runs {0,1 0 0,2 0 0,3 0 0,4 0 0,5 0 0,6 0
60 1,1 0 1,2 0 1,3 0 1,4 0 1,5 0 1,6 0}
72 foreach bit [split $bits ""] {
73 if {$bit == $prevbit} {
78 incr runs($prevbit,$run)
90 puts "[format %20s "Runs test"]:"
91 for {set i 1} {$i<=6} {incr i} {
92 eval test [list "$i zeroes"] %5d $runs(0,$i) $runlimits($i)
93 eval test [list "$i ones "] %5d $runs(0,$i) $runlimits($i)
96 test "Long Run test" %5d $longest 6 34
99 puts "Total result: FAILED!!!"