Search Apps Documentation Source Content File Folder Download Copy Actions Download

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}