rscache/util/
isaac_rand.rs1const GOLDEN_RATIO: u32 = 0x9e3779b9;
2const LOG_SIZE: u32 = 8;
3const SIZE: usize = 1 << LOG_SIZE;
4const MASK: u32 = (SIZE as u32 - 1) << 2;
5
6#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default)]
46pub struct IsaacRand {
47 a: u32,
48 b: u32,
49 c: u32,
50 count: usize,
51 mem: Vec<u32>,
52 rsl: Vec<u32>,
53}
54
55impl IsaacRand {
56 pub fn new(seed: &[u32]) -> Self {
58 let mem = vec![0; SIZE];
59 let mut rsl = vec![0; SIZE];
60 rsl[..seed.len()].clone_from_slice(seed);
61
62 let mut isaac = Self {
63 a: 0,
64 b: 0,
65 c: 0,
66 count: 0,
67 mem,
68 rsl,
69 };
70 isaac.init();
71 isaac
72 }
73 fn init(&mut self) {
74 let mut h = GOLDEN_RATIO;
75 let mut g = h;
76 let mut f = g;
77 let mut e = f;
78 let mut d = e;
79 let mut c = d;
80 let mut b = c;
81 let mut a = b;
82
83 let mut i = 0;
84 while i < 4 {
85 a ^= b << 11;
86 d = d.wrapping_add(a);
87 b = b.wrapping_add(c);
88 b ^= c >> 2;
89 e = e.wrapping_add(b);
90 c = c.wrapping_add(d);
91 c ^= d << 8;
92 f = f.wrapping_add(c);
93 d = d.wrapping_add(e);
94 d ^= e >> 16;
95 g = g.wrapping_add(d);
96 e = e.wrapping_add(f);
97 e ^= f << 10;
98 h = h.wrapping_add(e);
99 f = f.wrapping_add(g);
100 f ^= g >> 4;
101 a = a.wrapping_add(f);
102 g = g.wrapping_add(h);
103 g ^= h << 8;
104 b = b.wrapping_add(g);
105 h = h.wrapping_add(a);
106 h ^= a >> 9;
107 c = c.wrapping_add(h);
108 a = a.wrapping_add(b);
109 i += 1;
110 }
111
112 i = 0;
113 while i < SIZE {
114 a = a.wrapping_add(self.rsl[i]);
115 b = b.wrapping_add(self.rsl[i + 1]);
116 c = c.wrapping_add(self.rsl[i + 2]);
117 d = d.wrapping_add(self.rsl[i + 3]);
118 e = e.wrapping_add(self.rsl[i + 4]);
119 f = f.wrapping_add(self.rsl[i + 5]);
120 g = g.wrapping_add(self.rsl[i + 6]);
121 h = h.wrapping_add(self.rsl[i + 7]);
122
123 a ^= b << 11;
124 d = d.wrapping_add(a);
125 b = b.wrapping_add(c);
126 b ^= c >> 2;
127 e = e.wrapping_add(b);
128 c = c.wrapping_add(d);
129 c ^= d << 8;
130 f = f.wrapping_add(c);
131 d = d.wrapping_add(e);
132 d ^= e >> 16;
133 g = g.wrapping_add(d);
134 e = e.wrapping_add(f);
135 e ^= f << 10;
136 h = h.wrapping_add(e);
137 f = f.wrapping_add(g);
138 f ^= g >> 4;
139 a = a.wrapping_add(f);
140 g = g.wrapping_add(h);
141 g ^= h << 8;
142 b = b.wrapping_add(g);
143 h = h.wrapping_add(a);
144 h ^= a >> 9;
145 c = c.wrapping_add(h);
146 a = a.wrapping_add(b);
147 self.mem[i] = a;
148 self.mem[i + 1] = b;
149 self.mem[i + 2] = c;
150 self.mem[i + 3] = d;
151 self.mem[i + 4] = e;
152 self.mem[i + 5] = f;
153 self.mem[i + 6] = g;
154 self.mem[i + 7] = h;
155 i += 8;
156 }
157
158 i = 0;
159 while i < SIZE {
160 a = a.wrapping_add(self.mem[i]);
161 b = b.wrapping_add(self.mem[i + 1]);
162 c = c.wrapping_add(self.mem[i + 2]);
163 d = d.wrapping_add(self.mem[i + 3]);
164 e = e.wrapping_add(self.mem[i + 4]);
165 f = f.wrapping_add(self.mem[i + 5]);
166 g = g.wrapping_add(self.mem[i + 6]);
167 h = h.wrapping_add(self.mem[i + 7]);
168 a ^= b << 11;
169 d = d.wrapping_add(a);
170 b = b.wrapping_add(c);
171 b ^= c >> 2;
172 e = e.wrapping_add(b);
173 c = c.wrapping_add(d);
174 c ^= d << 8;
175 f = f.wrapping_add(c);
176 d = d.wrapping_add(e);
177 d ^= e >> 16;
178 g = g.wrapping_add(d);
179 e = e.wrapping_add(f);
180 e ^= f << 10;
181 h = h.wrapping_add(e);
182 f = f.wrapping_add(g);
183 f ^= g >> 4;
184 a = a.wrapping_add(f);
185 g = g.wrapping_add(h);
186 g ^= h << 8;
187 b = b.wrapping_add(g);
188 h = h.wrapping_add(a);
189 h ^= a >> 9;
190 c = c.wrapping_add(h);
191 a = a.wrapping_add(b);
192 self.mem[i] = a;
193 self.mem[i + 1] = b;
194 self.mem[i + 2] = c;
195 self.mem[i + 3] = d;
196 self.mem[i + 4] = e;
197 self.mem[i + 5] = f;
198 self.mem[i + 6] = g;
199 self.mem[i + 7] = h;
200 i += 8;
201 }
202
203 self.isaac();
204 self.count = SIZE;
205 }
206
207 fn isaac(&mut self) {
208 let mut i = 0;
209 let mut j = SIZE / 2;
210 let mut x;
211 let mut y;
212
213 self.c += 1;
214 self.b += self.c;
215 while i < SIZE / 2 {
216 x = self.mem[i];
217 self.a = self.a ^ (self.a << 13);
218 self.a = self.a.wrapping_add(self.mem[j]);
219 j += 1;
220 y = self.mem[((x & MASK) >> 2) as usize]
221 .wrapping_add(self.a)
222 .wrapping_add(self.b);
223 self.mem[i] = y;
224 self.b = self.mem[(((y >> LOG_SIZE) & MASK) >> 2) as usize].wrapping_add(x);
225 self.rsl[i] = self.b;
226 i += 1;
227
228 x = self.mem[i];
229 self.a = self.a ^ self.a >> 6;
230 self.a = self.a.wrapping_add(self.mem[j]);
231 j += 1;
232 y = self.mem[((x & MASK) >> 2) as usize]
233 .wrapping_add(self.a)
234 .wrapping_add(self.b);
235 self.mem[i] = y;
236 self.b = self.mem[(((y >> LOG_SIZE) & MASK) >> 2) as usize].wrapping_add(x);
237 self.rsl[i] = self.b;
238 i += 1;
239
240 x = self.mem[i];
241 self.a = self.a ^ (self.a << 2);
242 self.a = self.a.wrapping_add(self.mem[j]);
243 j += 1;
244 y = self.mem[((x & MASK) >> 2) as usize]
245 .wrapping_add(self.a)
246 .wrapping_add(self.b);
247 self.mem[i] = y;
248 self.b = self.mem[(((y >> LOG_SIZE) & MASK) >> 2) as usize].wrapping_add(x);
249 self.rsl[i] = self.b;
250 i += 1;
251
252 x = self.mem[i];
253 self.a = self.a ^ self.a >> 16;
254 self.a = self.a.wrapping_add(self.mem[j]);
255 j += 1;
256 y = self.mem[((x & MASK) >> 2) as usize]
257 .wrapping_add(self.a)
258 .wrapping_add(self.b);
259 self.mem[i] = y;
260 self.b = self.mem[(((y >> LOG_SIZE) & MASK) >> 2) as usize].wrapping_add(x);
261 self.rsl[i] = self.b;
262 i += 1;
263 }
264
265 j = 0;
266 while j < SIZE / 2 {
267 x = self.mem[i];
268 self.a = self.a ^ (self.a << 13);
269 self.a = self.a.wrapping_add(self.mem[j]);
270 j += 1;
271 y = self.mem[((x & MASK) >> 2) as usize]
272 .wrapping_add(self.a)
273 .wrapping_add(self.b);
274 self.mem[i] = y;
275 self.b = self.mem[(((y >> LOG_SIZE) & MASK) >> 2) as usize].wrapping_add(x);
276 self.rsl[i] = self.b;
277 i += 1;
278
279 x = self.mem[i];
280 self.a = self.a ^ self.a >> 6;
281 self.a = self.a.wrapping_add(self.mem[j]);
282 j += 1;
283 y = self.mem[((x & MASK) >> 2) as usize]
284 .wrapping_add(self.a)
285 .wrapping_add(self.b);
286 self.mem[i] = y;
287 self.b = self.mem[(((y >> LOG_SIZE) & MASK) >> 2) as usize].wrapping_add(x);
288 self.rsl[i] = self.b;
289 i += 1;
290
291 x = self.mem[i];
292 self.a = self.a ^ (self.a << 2);
293 self.a = self.a.wrapping_add(self.mem[j]);
294 j += 1;
295 y = self.mem[((x & MASK) >> 2) as usize]
296 .wrapping_add(self.a)
297 .wrapping_add(self.b);
298 self.mem[i] = y;
299 self.b = self.mem[(((y >> LOG_SIZE) & MASK) >> 2) as usize].wrapping_add(x);
300 self.rsl[i] = self.b;
301 i += 1;
302
303 x = self.mem[i];
304 self.a = self.a ^ self.a >> 16;
305 self.a = self.a.wrapping_add(self.mem[j]);
306 j += 1;
307 y = self.mem[((x & MASK) >> 2) as usize]
308 .wrapping_add(self.a)
309 .wrapping_add(self.b);
310 self.mem[i] = y;
311 self.b = self.mem[(((y >> LOG_SIZE) & MASK) >> 2) as usize].wrapping_add(x);
312 self.rsl[i] = self.b;
313 i += 1;
314 }
315 }
316}
317
318impl Iterator for IsaacRand {
319 type Item = u32;
320
321 fn next(&mut self) -> Option<Self::Item> {
322 if self.count == 0 {
323 self.isaac();
324 self.count = SIZE;
325 }
326 self.count -= 1;
327
328 Some(self.rsl[self.count])
329 }
330}