devela/num/rand/
xyza8.rs
1use crate::{ConstDefault, Own};
6
7#[doc = crate::doc_!(vendor: "8bit_rng")]
18#[must_use]
19#[derive(Clone, Copy, Debug, PartialEq, Eq)]
20pub struct Xyza8a {
21 x: u8,
22 y: u8,
23 z: u8,
24 a: u8,
25}
26
27impl Default for Xyza8a {
29 fn default() -> Self {
30 Self::DEFAULT
31 }
32}
33impl ConstDefault for Xyza8a {
35 const DEFAULT: Self = Self::new(Self::DEFAULT_SEED);
36}
37
38impl Xyza8a {
40 const DEFAULT_SEED: [u8; 4] = [0xDE, 0xFA, 0x00, 0x17];
41}
42
43impl Xyza8a {
44 pub const fn new(seeds: [u8; 4]) -> Self {
46 Self { x: seeds[0], y: seeds[1], z: seeds[2], a: seeds[3] }
47 }
48
49 #[must_use]
50 pub const fn inner_state(self) -> [u8; 4] {
52 [self.x, self.y, self.z, self.a]
53 }
54 pub const fn from_state(state: [u8; 4]) -> Self {
56 Self { x: state[0], y: state[1], z: state[2], a: state[3] }
57 }
58
59 #[must_use]
60 pub const fn current_u8(&self) -> u8 {
62 self.a
63 }
64 pub fn next_u8(&mut self) -> u8 {
66 let t = self.x ^ (self.x << 4);
67 self.x = self.y;
68 self.y = self.z;
69 self.z = self.a;
70 self.a = self.z ^ t ^ (self.z >> 1) ^ (t << 1);
71 self.a
72 }
73
74 pub const fn peek_next_state(&self) -> Self {
76 let mut new = *self;
77
78 let t = new.x ^ (new.x << 4);
79 new.x = new.y;
80 new.y = new.z;
81 new.z = new.a;
82 new.a = new.z ^ t ^ (new.z >> 1) ^ (t << 1);
83 new
84 }
85
86 pub const fn own_next_u8(self) -> Own<Self, u8> {
88 let s = self.peek_next_state();
89 let v = s.current_u8();
90 Own::new(s, v)
91 }
92}
93
94impl Xyza8a {
96 pub const fn new1_u32(seed: u32) -> Self {
100 Self::new(seed.to_le_bytes())
101 }
102
103 pub const fn new2_u16(seeds: [u16; 2]) -> Self {
107 let [x, y] = seeds[0].to_le_bytes();
108 let [z, a] = seeds[1].to_le_bytes();
109 Self::new([x, y, z, a])
110 }
111
112 pub const fn new4_u8(seeds: [u8; 4]) -> Self {
115 Self::new(seeds)
116 }
117}
118
119#[doc = crate::doc_!(vendor: "8bit_rng")]
130#[derive(Clone, Copy, Debug, PartialEq, Eq)]
131pub struct Xyza8b {
132 x: u8,
133 y: u8,
134 z: u8,
135 a: u8,
136}
137
138impl Default for Xyza8b {
139 fn default() -> Self {
140 Self::DEFAULT
141 }
142}
143impl ConstDefault for Xyza8b {
144 const DEFAULT: Self = Self::new(Self::DEFAULT_SEED);
145}
146
147impl Xyza8b {
149 const DEFAULT_SEED: [u8; 4] = [0xDE, 0xFA, 0x00, 0x17];
150}
151
152impl Xyza8b {
153 pub const fn new(seeds: [u8; 4]) -> Self {
156 Self { x: seeds[0], y: seeds[1], z: seeds[2], a: seeds[3] }
157 }
158
159 #[must_use]
160 pub const fn inner_state(self) -> [u8; 4] {
162 [self.x, self.y, self.z, self.a]
163 }
164 pub const fn from_state(state: [u8; 4]) -> Self {
166 Self { x: state[0], y: state[1], z: state[2], a: state[3] }
167 }
168
169 pub const fn current_u8(&self) -> u8 {
171 self.a
172 }
173
174 pub fn next_u8(&mut self) -> u8 {
176 let t = self.x ^ (self.x >> 1);
177 self.x = self.y;
178 self.y = self.z;
179 self.z = self.a;
180 self.a = self.z ^ t ^ (self.z >> 3) ^ (t << 1);
181 self.a
182 }
183
184 pub const fn peek_next_state(&self) -> Self {
186 let mut new = *self;
187
188 let t = new.x ^ (new.x >> 1);
189 new.x = new.y;
190 new.y = new.z;
191 new.z = new.a;
192 new.a = new.z ^ t ^ (new.z >> 3) ^ (t << 1);
193 new
194 }
195
196 pub const fn own_next_u8(self) -> Own<Self, u8> {
198 let s = self.peek_next_state();
199 let v = s.current_u8();
200 Own::new(s, v)
201 }
202}
203
204impl Xyza8b {
206 pub const fn new1_u32(seed: u32) -> Self {
210 Self::new(seed.to_le_bytes())
211 }
212
213 pub const fn new2_u16(seeds: [u16; 2]) -> Self {
217 let [x, y] = seeds[0].to_le_bytes();
218 let [z, b] = seeds[1].to_le_bytes();
219 Self::new([x, y, z, b])
220 }
221
222 pub const fn new4_u8(seeds: [u8; 4]) -> Self {
225 Self::new(seeds)
226 }
227}
228
229#[cfg(feature = "dep_rand_core")]
230#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "dep_rand_core")))]
231mod impl_rand {
232 use super::{Xyza8a, Xyza8b};
233 use crate::_dep::rand_core::{RngCore, SeedableRng};
234
235 impl RngCore for Xyza8a {
236 fn next_u32(&mut self) -> u32 {
238 u32::from_le_bytes([self.next_u8(), self.next_u8(), self.next_u8(), self.next_u8()])
239 }
240 fn next_u64(&mut self) -> u64 {
242 u64::from_le_bytes([
243 self.next_u8(),
244 self.next_u8(),
245 self.next_u8(),
246 self.next_u8(),
247 self.next_u8(),
248 self.next_u8(),
249 self.next_u8(),
250 self.next_u8(),
251 ])
252 }
253 fn fill_bytes(&mut self, dest: &mut [u8]) {
254 for byte in dest {
255 *byte = self.next_u8();
256 }
257 }
258 }
259 impl SeedableRng for Xyza8a {
260 type Seed = [u8; 4];
261 fn from_seed(seeds: Self::Seed) -> Self {
262 Self::new(seeds)
263 }
264 }
265
266 impl RngCore for Xyza8b {
267 fn next_u32(&mut self) -> u32 {
269 u32::from_le_bytes([self.next_u8(), self.next_u8(), self.next_u8(), self.next_u8()])
270 }
271 fn next_u64(&mut self) -> u64 {
273 u64::from_le_bytes([
274 self.next_u8(),
275 self.next_u8(),
276 self.next_u8(),
277 self.next_u8(),
278 self.next_u8(),
279 self.next_u8(),
280 self.next_u8(),
281 self.next_u8(),
282 ])
283 }
284 fn fill_bytes(&mut self, dest: &mut [u8]) {
285 for byte in dest {
286 *byte = self.next_u8();
287 }
288 }
289 }
290 impl SeedableRng for Xyza8b {
291 type Seed = [u8; 4];
292 fn from_seed(seeds: Self::Seed) -> Self {
293 Self::new(seeds)
294 }
295 }
296}