1use core::sync::atomic::AtomicUsize;
2use core::sync::atomic::Ordering::Relaxed;
3
4pub struct XorRand {
5 x: AtomicUsize,
6}
7
8impl XorRand {
9 pub fn new(seed: usize) -> Self {
10 Self {
11 x: AtomicUsize::new(seed),
12 }
13 }
14
15 pub fn rand(&self) -> usize {
16 let mut x = self.x.load(Relaxed);
17 x = self.x.fetch_xor(x.wrapping_shl(13), Relaxed);
18 x = self.x.fetch_xor(x.wrapping_shr(7), Relaxed);
19 self.x.fetch_xor(x.wrapping_shl(17), Relaxed);
20 self.x.load(Relaxed)
21 }
22
23 pub fn rand_range(&self, a: usize, b: usize) -> usize {
24 let m = b - a + 1;
25 return a + (self.rand() % m);
26 }
27}