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
use core::sync::atomic::AtomicUsize;
use core::sync::atomic::Ordering::Relaxed;

pub struct XorRand {
    x: AtomicUsize,
}

impl XorRand {
    pub fn new(seed: usize) -> Self {
        Self {
            x: AtomicUsize::new(seed),
        }
    }

    pub fn rand(&self) -> usize {
        let mut x = self.x.load(Relaxed);
        x = self.x.fetch_xor(x.wrapping_shl(13), Relaxed);
        x = self.x.fetch_xor(x.wrapping_shr(7), Relaxed);
        self.x.fetch_xor(x.wrapping_shl(17), Relaxed);
        self.x.load(Relaxed)
    }

    pub fn rand_range(&self, a: usize, b: usize) -> usize {
        let m = b - a + 1;
        return a + (self.rand() % m);
    }
}