rand/rngs/
xoshiro256plusplus.rs1use rand_core::impls::fill_bytes_via_next;
10use rand_core::le::read_u64_into;
11use rand_core::{RngCore, SeedableRng};
12#[cfg(feature = "serde")]
13use serde::{Deserialize, Serialize};
14
15#[derive(Debug, Clone, PartialEq, Eq)]
24#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
25pub struct Xoshiro256PlusPlus {
26 s: [u64; 4],
27}
28
29impl SeedableRng for Xoshiro256PlusPlus {
30 type Seed = [u8; 32];
31
32 #[inline]
35 fn from_seed(seed: [u8; 32]) -> Xoshiro256PlusPlus {
36 let mut state = [0; 4];
37 read_u64_into(&seed, &mut state);
38 if state.iter().all(|&x| x == 0) {
41 return Self::seed_from_u64(0);
42 }
43 Xoshiro256PlusPlus { s: state }
44 }
45
46 #[inline]
50 fn seed_from_u64(mut state: u64) -> Self {
51 const PHI: u64 = 0x9e3779b97f4a7c15;
52 let mut s = [0; 4];
53 for i in s.iter_mut() {
54 state = state.wrapping_add(PHI);
55 let mut z = state;
56 z = (z ^ (z >> 30)).wrapping_mul(0xbf58476d1ce4e5b9);
57 z = (z ^ (z >> 27)).wrapping_mul(0x94d049bb133111eb);
58 z = z ^ (z >> 31);
59 *i = z;
60 }
61 debug_assert_ne!(s, [0; 4]);
64 Xoshiro256PlusPlus { s }
65 }
66}
67
68impl RngCore for Xoshiro256PlusPlus {
69 #[inline]
70 fn next_u32(&mut self) -> u32 {
71 let val = self.next_u64();
74 (val >> 32) as u32
75 }
76
77 #[inline]
78 fn next_u64(&mut self) -> u64 {
79 let res = self.s[0]
80 .wrapping_add(self.s[3])
81 .rotate_left(23)
82 .wrapping_add(self.s[0]);
83
84 let t = self.s[1] << 17;
85
86 self.s[2] ^= self.s[0];
87 self.s[3] ^= self.s[1];
88 self.s[1] ^= self.s[2];
89 self.s[0] ^= self.s[3];
90
91 self.s[2] ^= t;
92
93 self.s[3] = self.s[3].rotate_left(45);
94
95 res
96 }
97
98 #[inline]
99 fn fill_bytes(&mut self, dst: &mut [u8]) {
100 fill_bytes_via_next(self, dst)
101 }
102}
103
104#[cfg(test)]
105mod tests {
106 use super::Xoshiro256PlusPlus;
107 use rand_core::{RngCore, SeedableRng};
108
109 #[test]
110 fn reference() {
111 let mut rng = Xoshiro256PlusPlus::from_seed([
112 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0,
113 0, 0, 0,
114 ]);
115 let expected = [
118 41943041,
119 58720359,
120 3588806011781223,
121 3591011842654386,
122 9228616714210784205,
123 9973669472204895162,
124 14011001112246962877,
125 12406186145184390807,
126 15849039046786891736,
127 10450023813501588000,
128 ];
129 for &e in &expected {
130 assert_eq!(rng.next_u64(), e);
131 }
132 }
133
134 #[test]
135 fn stable_seed_from_u64() {
136 let mut rng = Xoshiro256PlusPlus::seed_from_u64(0);
139 let expected = [
140 5987356902031041503,
141 7051070477665621255,
142 6633766593972829180,
143 211316841551650330,
144 9136120204379184874,
145 379361710973160858,
146 15813423377499357806,
147 15596884590815070553,
148 5439680534584881407,
149 1369371744833522710,
150 ];
151 for &e in &expected {
152 assert_eq!(rng.next_u64(), e);
153 }
154 }
155}