1use rand::{CryptoRng, Error, RngCore};
20
21pub struct Pcg32 {
22 state: u64,
23 increment: u64,
24}
25
26impl Pcg32 {
27 const MULTIPLIER: u64 = 6364136223846793005;
28 const INCREMENT: u64 = 1442695040888963407;
29
30 pub fn new(seed: u64) -> Self {
31 let mut rng = Self { state: 0, increment: Self::INCREMENT | 1 };
32 rng.state = rng.state.wrapping_add(seed);
33 rng.state = rng.state.wrapping_mul(Self::MULTIPLIER).wrapping_add(rng.increment);
34 rng
35 }
36
37 fn next_u32(&mut self) -> u32 {
38 let old_state = self.state;
39 self.state = old_state.wrapping_mul(Self::MULTIPLIER).wrapping_add(self.increment);
40 let xorshifted = ((old_state >> 18) ^ old_state) >> 27;
41 let rot = old_state >> 59;
42 ((xorshifted >> rot) | (xorshifted << ((!rot).wrapping_add(1) & 31))) as u32
43 }
44}
45
46impl CryptoRng for Pcg32 {}
47
48impl RngCore for Pcg32 {
49 fn next_u32(&mut self) -> u32 {
50 self.next_u32()
51 }
52
53 fn next_u64(&mut self) -> u64 {
54 ((self.next_u32() as u64) << 32) | (self.next_u32() as u64)
55 }
56
57 fn fill_bytes(&mut self, dest: &mut [u8]) {
58 let mut i = 0;
59 while i + 4 <= dest.len() {
60 let bytes = self.next_u32().to_le_bytes();
61 dest[i..i + 4].copy_from_slice(&bytes);
62 i += 4;
63 }
64 if i < dest.len() {
65 let bytes = self.next_u32().to_le_bytes();
66 for (j, dest_byte) in dest[i..].iter_mut().enumerate() {
67 *dest_byte = bytes[j];
68 }
69 }
70 }
71
72 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
73 self.fill_bytes(dest);
74 Ok(())
75 }
76}
77
78#[cfg(test)]
79mod tests {
80 use super::*;
81
82 #[test]
83 fn test_pcg() {
84 const ITERS: usize = 10000;
85
86 let mut rng0 = Pcg32::new(42);
87 let mut rng1 = Pcg32::new(42);
88
89 for i in 0..ITERS {
90 let a = rng0.next_u32();
91 let b = rng1.next_u32();
92 assert!(a == b);
93
94 let a = rng0.next_u64();
95 let b = rng1.next_u64();
96 assert!(a == b);
97
98 let mut buf0 = vec![0u8; i];
99 let mut buf1 = vec![0u8; i];
100 rng0.fill_bytes(&mut buf0);
101 rng1.fill_bytes(&mut buf1);
102 assert!(buf0 == buf1);
103 }
104 }
105}