isaac_test.gno
3.40 Kb ยท 164 lines
1package isaac
2
3import (
4 "math/rand"
5 "testing"
6)
7
8type OpenISAAC struct {
9 Randrsl [256]uint32
10 Randcnt uint32
11 Mm [256]uint32
12 Aa, Bb, Cc uint32
13 Seed [256]uint32
14}
15
16func TestISAACSeeding(t *testing.T) {
17 _ = New()
18}
19
20func TestISAACRand(t *testing.T) {
21 rnd := New(987654321)
22 rng := rand.New(rnd)
23
24 expected := []float64{
25 0.3590173976876423,
26 0.7045500585814575,
27 0.3307624938209778,
28 0.9174646414250772,
29 0.11232269485263391,
30 0.9276658847827113,
31 0.9561549853128902,
32 0.3921638978394879,
33 0.9824881209760224,
34 0.8213784955963486,
35 }
36
37 for i, exp := range expected {
38 val := rng.Float64()
39 if exp != val {
40 t.Errorf("Rand.Float64() at iteration %d: got %g, expected %g", i, val, exp)
41 }
42 }
43}
44
45func TestISAACUint64(t *testing.T) {
46 rnd := New(1000)
47
48 expected := []uint64{
49 13706738165129397958,
50 11158865851759859683,
51 7282911433372880595,
52 10191257834247701829,
53 6756510588635422211,
54 9188469355127567259,
55 3870407692778398450,
56 7510499000403643056,
57 11921506945015596058,
58 5594436529078496461,
59 }
60
61 for i, exp := range expected {
62 val := rnd.Uint64()
63 if exp != val {
64 t.Errorf("ISAAC.Uint64() at iteration %d: got %d, expected %d", i, val, exp)
65 }
66 }
67}
68
69func dupState(i *ISAAC) *OpenISAAC {
70 state := &OpenISAAC{}
71 state.Seed = i.seed
72 state.Randrsl = i.randrsl
73 state.Mm = i.mm
74 state.Aa = i.aa
75 state.Bb = i.bb
76 state.Cc = i.cc
77 state.Randcnt = i.randcnt
78
79 return state
80}
81
82func TestISAACMarshalUnmarshal(t *testing.T) {
83 rnd := New(1001)
84
85 expected1 := []uint64{
86 15520355889829550420,
87 14048062122838424762,
88 17386984608929258959,
89 6631892771034928162,
90 10939419587267807737,
91 }
92
93 expected2 := []uint64{
94 3835981378089717525,
95 13955658256492919532,
96 10077846634918708781,
97 5773204650675356768,
98 4971527406542890875,
99 }
100
101 for i, exp := range expected1 {
102 val := rnd.Uint64()
103 if exp != val {
104 t.Errorf("ISAAC.Uint64() at iteration %d: got %d, expected %d", i, val, exp)
105 }
106 }
107
108 marshalled, err := rnd.MarshalBinary()
109
110 // t.Logf("State: [%v]\n", dupState(rnd))
111 // t.Logf("Marshalled State: [%x] -- %v\n", marshalled, err)
112 state_before := dupState(rnd)
113
114 if err != nil {
115 t.Errorf("ISAAC.MarshalBinary() error: %v", err)
116 }
117
118 // Advance state by one number; then check the next 5. The expectation is that they _will_ fail.
119 rnd.Uint64()
120
121 for i, exp := range expected2 {
122 val := rnd.Uint64()
123 if exp == val {
124 t.Errorf(" Iteration %d matched %d; which is from iteration %d; something strange is happening.", (i + 6), val, (i + 5))
125 }
126 }
127
128 // t.Logf("State before unmarshall: [%v]\n", dupState(rnd))
129
130 // Now restore the state of the PRNG
131 err = rnd.UnmarshalBinary(marshalled)
132
133 // t.Logf("State after unmarshall: [%v]\n", dupState(rnd))
134
135 if state_before.Seed != dupState(rnd).Seed {
136 t.Errorf("Seed mismatch")
137 }
138 if state_before.Randrsl != dupState(rnd).Randrsl {
139 t.Errorf("Randrsl mismatch")
140 }
141 if state_before.Mm != dupState(rnd).Mm {
142 t.Errorf("Mm mismatch")
143 }
144 if state_before.Aa != dupState(rnd).Aa {
145 t.Errorf("Aa mismatch")
146 }
147 if state_before.Bb != dupState(rnd).Bb {
148 t.Errorf("Bb mismatch")
149 }
150 if state_before.Cc != dupState(rnd).Cc {
151 t.Errorf("Cc mismatch")
152 }
153 if state_before.Randcnt != dupState(rnd).Randcnt {
154 t.Errorf("Randcnt mismatch")
155 }
156
157 // Now we should be back on track for the last 5 numbers
158 for i, exp := range expected2 {
159 val := rnd.Uint64()
160 if exp != val {
161 t.Errorf("ISAAC.Uint64() at iteration %d: got %d, expected %d", (i + 5), val, exp)
162 }
163 }
164}