isaac64_test.gno
3.47 Kb ยท 165 lines
1package isaac64
2
3import (
4 "math/rand"
5 "testing"
6)
7
8type OpenISAAC struct {
9 Randrsl [256]uint64
10 Randcnt uint64
11 Mm [256]uint64
12 Aa, Bb, Cc uint64
13 Seed [256]uint64
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 outputs for the first 5 random floats with the given seed
25 expected := []float64{
26 0.2818878834295122,
27 0.8575461830821571,
28 0.9878021063787968,
29 0.6503544780116336,
30 0.5158329690433359,
31 0.7959152461588924,
32 0.5432366486934906,
33 0.824665978209607,
34 0.8615372170680458,
35 0.22954589404739578,
36 }
37
38 for i, exp := range expected {
39 val := rng.Float64()
40 if exp != val {
41 t.Errorf("Rand.Float64() at iteration %d: got %g, expected %g", i, val, exp)
42 }
43 }
44}
45
46func TestISAACUint64(t *testing.T) {
47 rnd := New(1000)
48
49 expected := []uint64{
50 10083220283665581455,
51 10039389761195725041,
52 6820016387036140989,
53 6784213597523088182,
54 13120722600477653778,
55 3491117614651563646,
56 1297676147275528930,
57 15006384980354042338,
58 3104467119059991036,
59 4914319123654344819,
60 }
61
62 for i, exp := range expected {
63 val := rnd.Uint64()
64 if exp != val {
65 t.Errorf("ISAAC.Uint64() at iteration %d: got %d, expected %d", i, val, exp)
66 }
67 }
68}
69
70func dupState(i *ISAAC) *OpenISAAC {
71 state := &OpenISAAC{}
72 state.Seed = i.seed
73 state.Randrsl = i.randrsl
74 state.Mm = i.mm
75 state.Aa = i.aa
76 state.Bb = i.bb
77 state.Cc = i.cc
78 state.Randcnt = i.randcnt
79
80 return state
81}
82
83func TestISAACMarshalUnmarshal(t *testing.T) {
84 rnd := New(1001)
85
86 expected1 := []uint64{
87 4398183556077595549,
88 14479654616302101831,
89 15852653767232940552,
90 2801765968457115882,
91 8875575139772470433,
92 }
93
94 expected2 := []uint64{
95 17583056722733587141,
96 16906215529544723388,
97 7599862885469865851,
98 9623269843822592805,
99 4311429062865512072,
100 }
101
102 for i, exp := range expected1 {
103 val := rnd.Uint64()
104 if exp != val {
105 t.Errorf("ISAAC.Uint64() at iteration %d: got %d, expected %d", i, val, exp)
106 }
107 }
108
109 marshalled, err := rnd.MarshalBinary()
110
111 // t.Logf("State: [%v]\n", dupState(rnd))
112 // t.Logf("Marshalled State: [%x] -- %v\n", marshalled, err)
113 state_before := dupState(rnd)
114
115 if err != nil {
116 t.Errorf("ISAAC.MarshalBinary() error: %v", err)
117 }
118
119 // Advance state by one number; then check the next 5. The expectation is that they _will_ fail.
120 rnd.Uint64()
121
122 for i, exp := range expected2 {
123 val := rnd.Uint64()
124 if exp == val {
125 t.Errorf(" Iteration %d matched %d; which is from iteration %d; something strange is happening.", (i + 6), val, (i + 5))
126 }
127 }
128
129 // t.Logf("State before unmarshall: [%v]\n", dupState(rnd))
130
131 // Now restore the state of the PRNG
132 err = rnd.UnmarshalBinary(marshalled)
133
134 // t.Logf("State after unmarshall: [%v]\n", dupState(rnd))
135
136 if state_before.Seed != dupState(rnd).Seed {
137 t.Errorf("Seed mismatch")
138 }
139 if state_before.Randrsl != dupState(rnd).Randrsl {
140 t.Errorf("Randrsl mismatch")
141 }
142 if state_before.Mm != dupState(rnd).Mm {
143 t.Errorf("Mm mismatch")
144 }
145 if state_before.Aa != dupState(rnd).Aa {
146 t.Errorf("Aa mismatch")
147 }
148 if state_before.Bb != dupState(rnd).Bb {
149 t.Errorf("Bb mismatch")
150 }
151 if state_before.Cc != dupState(rnd).Cc {
152 t.Errorf("Cc mismatch")
153 }
154 if state_before.Randcnt != dupState(rnd).Randcnt {
155 t.Errorf("Randcnt mismatch")
156 }
157
158 // Now we should be back on track for the last 5 numbers
159 for i, exp := range expected2 {
160 val := rnd.Uint64()
161 if exp != val {
162 t.Errorf("ISAAC.Uint64() at iteration %d: got %d, expected %d", (i + 5), val, exp)
163 }
164 }
165}