ya_rand/
xoshiro256pp.rs

1use crate::{
2    rng::{SeedableYARandGenerator, YARandGenerator},
3    util::{state_from_entropy, state_from_seed},
4};
5
6/// Rust implementation of the xoshiro256++ PRNG.
7/// This generator is fast, high-quality, and small,
8/// but not cryptographically secure.
9///
10/// More information can be found at: <https://prng.di.unimi.it/>.
11#[derive(Debug, PartialEq, Eq)]
12pub struct Xoshiro256pp {
13    state: [u64; 4],
14}
15
16impl Default for Xoshiro256pp {
17    #[inline]
18    fn default() -> Self {
19        Self::new_with_seed(0)
20    }
21}
22
23impl SeedableYARandGenerator for Xoshiro256pp {
24    fn new_with_seed(seed: u64) -> Self {
25        let state = state_from_seed(seed);
26        Self { state }
27    }
28}
29
30impl YARandGenerator for Xoshiro256pp {
31    fn try_new() -> Result<Self, getrandom::Error> {
32        let state = state_from_entropy()?;
33        Ok(Self { state })
34    }
35
36    #[cfg_attr(feature = "inline", inline)]
37    fn u64(&mut self) -> u64 {
38        let result = self.state[0]
39            .wrapping_add(self.state[3])
40            .rotate_left(23)
41            .wrapping_add(self.state[0]);
42        let temp = self.state[1] << 17;
43
44        self.state[2] ^= self.state[0];
45        self.state[3] ^= self.state[1];
46        self.state[1] ^= self.state[2];
47        self.state[0] ^= self.state[3];
48
49        self.state[2] ^= temp;
50        self.state[3] = self.state[3].rotate_left(45);
51
52        result
53    }
54}