-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrandom.c
122 lines (102 loc) · 2.71 KB
/
random.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/*****************************
Human readable C version of ISAAC rng.
*****************************/
#include <stdio.h>
#include <stddef.h>
/* a ub4 is an unsigned 4-byte quantity */
typedef unsigned long int ub4;
/* external results */
ub4 randrsl[256], randcnt;
/* internal state */
static ub4 mm[256];
static ub4 aa=0, bb=0, cc=0;
void isaac()
{
register ub4 i,x,y;
cc = cc + 1; /* cc just gets incremented once per 256 results */
bb = bb + cc; /* then combined with bb */
for (i=0; i<256; ++i)
{
x = mm[i];
switch (i%4)
{
case 0: aa = aa^(aa<<13); break;
case 1: aa = aa^(aa>>6); break;
case 2: aa = aa^(aa<<2); break;
case 3: aa = aa^(aa>>16); break;
}
aa = mm[(i+128)%256] + aa;
mm[i] = y = mm[(x>>2)%256] + aa + bb;
randrsl[i] = bb = mm[(y>>10)%256] + x;
/* Note that bits 2..9 are chosen from x but 10..17 are chosen
from y. The only important thing here is that 2..9 and 10..17
don't overlap. 2..9 and 10..17 were then chosen for speed in
the optimized version (rand.c) */
/* See http://burtleburtle.net/bob/rand/isaac.html
for further explanations and analysis. */
}
}
/* if (flag!=0), then use the contents of randrsl[] to initialize mm[]. */
#define mix(a,b,c,d,e,f,g,h) \
{ \
a^=b<<11; d+=a; b+=c; \
b^=c>>2; e+=b; c+=d; \
c^=d<<8; f+=c; d+=e; \
d^=e>>16; g+=d; e+=f; \
e^=f<<10; h+=e; f+=g; \
f^=g>>4; a+=f; g+=h; \
g^=h<<8; b+=g; h+=a; \
h^=a>>9; c+=h; a+=b; \
}
void randinit(flag)
int flag;
{
int i;
ub4 a,b,c,d,e,f,g,h;
aa=bb=cc=0;
a=b=c=d=e=f=g=h=0x9e3779b9; /* the golden ratio */
for (i=0; i<4; ++i) /* scramble it */
{
mix(a,b,c,d,e,f,g,h);
}
for (i=0; i<256; i+=8) /* fill in mm[] with messy stuff */
{
if (flag) /* use all the information in the seed */
{
a+=randrsl[i ]; b+=randrsl[i+1]; c+=randrsl[i+2]; d+=randrsl[i+3];
e+=randrsl[i+4]; f+=randrsl[i+5]; g+=randrsl[i+6]; h+=randrsl[i+7];
}
mix(a,b,c,d,e,f,g,h);
mm[i ]=a; mm[i+1]=b; mm[i+2]=c; mm[i+3]=d;
mm[i+4]=e; mm[i+5]=f; mm[i+6]=g; mm[i+7]=h;
}
if (flag)
{ /* do a second pass to make all of the seed affect all of mm */
for (i=0; i<256; i+=8)
{
a+=mm[i ]; b+=mm[i+1]; c+=mm[i+2]; d+=mm[i+3];
e+=mm[i+4]; f+=mm[i+5]; g+=mm[i+6]; h+=mm[i+7];
mix(a,b,c,d,e,f,g,h);
mm[i ]=a; mm[i+1]=b; mm[i+2]=c; mm[i+3]=d;
mm[i+4]=e; mm[i+5]=f; mm[i+6]=g; mm[i+7]=h;
}
}
isaac(); /* fill in the first set of results */
randcnt=256; /* prepare to use the first set of results */
}
int main()
{
ub4 i,j;
aa=bb=cc=(ub4)0;
for (i=0; i<256; ++i) mm[i]=randrsl[i]=(ub4)0;
randinit(1);
for (i=0; i<2; ++i)
{
isaac();
for (j=0; j<256; ++j)
{
printf("%.8lx",randrsl[j]);
if ((j&7)==7) printf("\n");
}
}
}