lib_q_random/
deterministic_rng.rs1use core::convert::Infallible;
7
8use rand_core::{
9 SeedableRng,
10 TryRng,
11};
12
13#[derive(Clone, Copy, Debug)]
19pub struct DeterministicRng {
20 state: u64,
21}
22
23impl DeterministicRng {
24 #[must_use]
26 pub fn seed_from_u64(seed: u64) -> Self {
27 let mut s = seed.wrapping_add(0x9E37_79B9_7F4A_7C15);
29 s = (s ^ (s >> 30)).wrapping_mul(0xBF58_476D_1CE4_E5B9);
30 s = (s ^ (s >> 27)).wrapping_mul(0x94D0_49BB_1331_11EB);
31 s ^= s >> 31;
32 Self {
33 state: if s == 0 { 1 } else { s },
34 }
35 }
36
37 #[inline]
38 fn next_u64_inner(&mut self) -> u64 {
39 let mut x = self.state;
41 x ^= x << 13;
42 x ^= x >> 7;
43 x ^= x << 17;
44 self.state = x;
45 x
46 }
47}
48
49impl TryRng for DeterministicRng {
50 type Error = Infallible;
51
52 fn try_next_u32(&mut self) -> Result<u32, Self::Error> {
53 Ok((self.next_u64_inner() & 0xFFFF_FFFF) as u32)
54 }
55
56 fn try_next_u64(&mut self) -> Result<u64, Self::Error> {
57 Ok(self.next_u64_inner())
58 }
59
60 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Self::Error> {
61 let mut i = 0;
62 while i < dest.len() {
63 let u = self.next_u64_inner().to_le_bytes();
64 let n = (dest.len() - i).min(8);
65 dest[i..i + n].copy_from_slice(&u[..n]);
66 i += n;
67 }
68 Ok(())
69 }
70}
71
72impl SeedableRng for DeterministicRng {
73 type Seed = [u8; 8];
74
75 fn from_seed(seed: Self::Seed) -> Self {
76 Self::seed_from_u64(u64::from_le_bytes(seed))
77 }
78}