ya_rand/rng.rs
1use crate::util;
2use core::ptr;
3
4#[cfg(all(feature = "alloc", feature = "secure"))]
5use {
6 crate::encoding::Encoder,
7 alloc::{string::String, vec, vec::Vec},
8};
9
10const F64_MANT: u32 = f64::MANTISSA_DIGITS;
11const F32_MANT: u32 = f32::MANTISSA_DIGITS;
12const F64_MAX_PRECISE: u64 = 1 << F64_MANT;
13const F32_MAX_PRECISE: u64 = 1 << F32_MANT;
14const F64_DIVISOR: f64 = F64_MAX_PRECISE as f64;
15const F32_DIVISOR: f32 = F32_MAX_PRECISE as f32;
16pub const ALPHANUMERIC: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
17
18/// Trait for RNGs that provide cryptographically secure data.
19pub trait SecureGenerator: Generator {
20 /// Fills `dst` with random data, which is safe to be used in cryptographic contexts.
21 ///
22 /// # Examples
23 ///
24 /// ```
25 /// use ya_rand::*;
26 ///
27 /// let mut rng = new_rng_secure();
28 /// let mut data = [0; 1738];
29 /// rng.fill_bytes(&mut data);
30 /// assert!(data.into_iter().any(|v| v != 0));
31 /// ```
32 fn fill_bytes(&mut self, dst: &mut [u8]);
33
34 /// Fills `dst` with random data, which is safe to be used in cryptographic contexts.
35 ///
36 /// Differs from [`SecureGenerator::fill_bytes`] in that the underlying type of `dst`
37 /// doesn't need to be a specific type (see safety comment).
38 ///
39 /// # Examples
40 ///
41 /// ```
42 /// use ya_rand::*;
43 ///
44 /// #[repr(C)]
45 /// #[derive(Clone, Copy, Default, PartialEq, Eq)]
46 /// struct NotAByte {
47 /// x: u16,
48 /// y: u32,
49 /// z: u64,
50 /// }
51 ///
52 /// let mut rng = new_rng_secure();
53 /// let zero_value = NotAByte::default();
54 /// let mut data = [zero_value; 69];
55 /// unsafe {
56 /// rng.fill_raw(&mut data);
57 /// }
58 /// assert!(data.into_iter().any(|v| v != zero_value));
59 /// ```
60 ///
61 /// # Safety
62 ///
63 /// `T` must be valid as nothing more than a collection of bytes.
64 /// Integer types are the simplest example of this, but structs of integer
65 /// types generally should fall under the same umbrella.
66 #[inline]
67 unsafe fn fill_raw<T>(&mut self, dst: &mut [T]) {
68 // SAFETY: The caller has promised not to be a fucking dumbass.
69 let dst_as_bytes = unsafe { util::as_raw_bytes_mut(dst) };
70 self.fill_bytes(dst_as_bytes);
71 }
72
73 /// Generates a random `String` with length `len`, using the provided
74 /// `Encoder` to determine character set and minimum secure length. Because
75 /// character sets can only contain valid ascii values, the length of the created
76 /// `String` reprensents both the size of the `String` in bytes, and the
77 /// amount of characters it contains.
78 ///
79 /// Values of `len` which are less than what would be considered secure for the
80 /// `Encoder` being used will be silently promoted to the minimum secure length.
81 ///
82 /// All provided encoders are accessible via [`crate::encoding`].
83 /// Users wishing to implement their own encoding scheme must do so
84 /// through the [`Encoder`] trait.
85 ///
86 /// Originally inspired by golang's addition of [`rand.Text`] in release 1.24,
87 /// but altered to be encoding/length generic and unbiased for non-trivial bases.
88 ///
89 /// [`rand.Text`]:
90 /// https://cs.opensource.google/go/go/+/refs/tags/go1.24.0:src/crypto/rand/text.go
91 ///
92 /// # Examples
93 ///
94 /// ```
95 /// use ya_rand::*;
96 /// use ya_rand::encoding::Base16;
97 ///
98 /// const LEN: usize = 420;
99 /// let mut rng = new_rng_secure();
100 /// let hex_string = rng.text::<Base16>(LEN);
101 /// assert!(hex_string.len() == LEN);
102 /// assert!(hex_string.bytes().count() == LEN);
103 /// assert!(hex_string.chars().count() == LEN);
104 /// for c in hex_string.bytes() {
105 /// assert!(
106 /// (b'0' <= c && c <= b'9') ||
107 /// (b'A' <= c && c <= b'F')
108 /// );
109 /// }
110 /// ```
111 #[cfg(all(feature = "alloc", feature = "secure"))]
112 #[inline(never)]
113 fn text<E: Encoder>(&mut self, len: usize) -> String {
114 const BYTE_VALUES: usize = 1 << u8::BITS;
115 // Force all values of the vector to be initialized to a
116 // non-zero value. This guarantees all the allocated memory
117 // will be page-faulted and can massively improve performance
118 // when encoding long strings.
119 let mut bytes = vec![u8::MAX; len.max(E::MIN_LEN)];
120 if BYTE_VALUES % E::CHARSET.len() == 0 {
121 self.fill_bytes(&mut bytes);
122 // Directly map each random u8 to a character in the set.
123 // This approach is extremely efficient, but only produces
124 // unbiased random sequences when the length of the current
125 // `CHARSET` is divisible by the amount of possible u8 values,
126 // which is why we need a fallback approach.
127 for cur in &mut bytes {
128 let random_index = *cur as usize;
129 *cur = E::CHARSET[random_index % E::CHARSET.len()];
130 }
131 } else {
132 // Alternative approach that's potentially much slower,
133 // but always produces unbiased results.
134 // The unwrap gets optimized out since rust can see that
135 // `E::CHARSET` has a non-zero length.
136 bytes.fill_with(|| *self.choose(E::CHARSET).unwrap());
137 }
138 // SAFETY: All provided encoders only use ascii values, and
139 // custom `Encoder` implementations agree to do the same when
140 // implementing the trait.
141 unsafe { String::from_utf8_unchecked(bytes) }
142 }
143}
144
145/// Trait for RNGs that can be created from a user-provided seed.
146pub trait SeedableGenerator: Generator + Default {
147 /// Creates a generator from the output of an internal PRNG,
148 /// which is itself seeded from `seed`.
149 ///
150 /// As a rule: unless you are **absolutely certain** that you need to manually
151 /// seed a generator, you don't.
152 /// Instead, use [`crate::new_rng`] when you need to create a new instance.
153 ///
154 /// If you have a scenario where you really do need a set seed, prefer using the
155 /// `Default` implementation of the desired generator.
156 ///
157 /// # Examples
158 ///
159 /// ```
160 /// use ya_rand::*;
161 ///
162 /// let mut rng1 = ShiroRng::new_with_seed(0);
163 /// // Default initialization is just a shortcut for explicitly seeding with 0.
164 /// let mut rng2 = ShiroRng::default();
165 /// assert!(rng1 == rng2);
166 ///
167 /// let result1 = rng1.u64();
168 /// let result2 = rng2.u64();
169 /// assert!(result1 == result2);
170 /// ```
171 fn new_with_seed(seed: u64) -> Self;
172}
173
174/// Base trait that all RNGs must implement.
175pub trait Generator: Sized {
176 /// Creates a generator using randomness provided by the OS.
177 ///
178 /// Unlike [`Generator::new`], which will panic on failure, `try_new`
179 /// propagates the error-handling responsibility to the user. But the probability
180 /// of your operating systems RNG failing is absurdly low, and in the rare case that it
181 /// does fail, that's not really an issue most users are going to be able to address.
182 ///
183 /// Stick to using [`crate::new_rng`], unless you really need a generator of a
184 /// different type (you probably don't), then use `new` on your desired type.
185 fn try_new() -> Result<Self, getrandom::Error>;
186
187 /// Returns a uniformly distributed `u64` in the interval [0, 2<sup>64</sup>).
188 fn u64(&mut self) -> u64;
189
190 /// Creates a generator using randomness provided by the OS.
191 ///
192 /// It is recommended to use the top-level [`crate::new_rng`] instead
193 /// of calling this function on a specific generator type.
194 ///
195 /// # Examples
196 ///
197 /// ```
198 /// use ya_rand::*;
199 ///
200 /// // Recommended usage
201 /// let mut rng1 = new_rng();
202 /// // More explicit
203 /// let mut rng2 = ShiroRng::new();
204 /// // Even more explicit
205 /// let mut rng3 = Xoshiro256pp::new();
206 /// // Since these are all created using OS entropy, the odds of
207 /// // their initial states colliding is vanishingly small.
208 /// assert!(rng1 != rng2);
209 /// assert!(rng1 != rng3);
210 /// assert!(rng2 != rng3);
211 /// ```
212 ///
213 /// # Safety
214 ///
215 /// This function will panic if your OS rng fails to provide enough entropy.
216 /// But this is extremely unlikely, and unless you're working at the kernel level it's
217 /// not something you should ever be concerned with.
218 ///
219 /// Since Windows 10 this function is infallible, thanks to modern Windows versions adopting
220 /// a user-space cryptographic architecture that can't fail during runtime.
221 #[inline]
222 fn new() -> Self {
223 Self::try_new().expect("retrieving random data from the operating system should never fail")
224 }
225
226 /// Returns a uniformly distributed `usize` in the interval \[0, `usize::MAX`\].
227 #[inline]
228 fn usize(&mut self) -> usize {
229 self.bits(usize::BITS) as usize
230 }
231
232 /// Returns a uniformly distributed `u32` in the interval [0, 2<sup>32</sup>).
233 #[inline]
234 fn u32(&mut self) -> u32 {
235 self.bits(u32::BITS) as u32
236 }
237
238 /// Returns a uniformly distributed `u16` in the interval [0, 2<sup>16</sup>).
239 #[inline]
240 fn u16(&mut self) -> u16 {
241 self.bits(u16::BITS) as u16
242 }
243
244 /// Returns a uniformly distributed `u8` in the interval [0, 2<sup>8</sup>).
245 #[inline]
246 fn u8(&mut self) -> u8 {
247 self.bits(u8::BITS) as u8
248 }
249
250 /// Returns a uniformly distributed `u64` in the interval [0, 2<sup>`bit_count`</sup>).
251 ///
252 /// The value of `bit_count` is clamped to 64.
253 #[inline]
254 fn bits(&mut self, bit_count: u32) -> u64 {
255 self.u64() >> (u64::BITS - bit_count.min(u64::BITS))
256 }
257
258 /// A simple coinflip, returning a `bool` that has a 50% chance of being true.
259 ///
260 /// # Examples
261 ///
262 /// ```
263 /// use ya_rand::*;
264 ///
265 /// const ITERATIONS: u64 = 1 << 24;
266 /// let mut rng = new_rng();
267 /// let mut yes: u64 = 0;
268 /// let mut no: u64 = 0;
269 /// for _ in 0..ITERATIONS {
270 /// if rng.bool() {
271 /// yes += 1;
272 /// } else {
273 /// no += 1;
274 /// }
275 /// }
276 /// // We expect the difference to be within ~5%.
277 /// let THRESHOLD: u64 = ITERATIONS / 20;
278 /// assert!(yes.abs_diff(no) <= THRESHOLD);
279 /// ```
280 #[inline]
281 fn bool(&mut self) -> bool {
282 // Compiles to a single "shr 63" instruction.
283 self.bits(1) == 1
284 }
285
286 /// Returns a uniformly distributed `u64` in the interval [0, `max`).
287 ///
288 /// Using [`Generator::bits`] when `max` happens to be a power of 2
289 /// will be significantly faster.
290 ///
291 /// # Examples
292 ///
293 /// ```
294 /// use ya_rand::*;
295 ///
296 /// let mut rng = new_rng();
297 /// // Special case: bound of 0 always returns 0.
298 /// assert!(rng.bound(0) == 0);
299 /// for i in 1..=2000 {
300 /// for _ in 0..(i * 2) {
301 /// assert!(rng.bound(i) < i);
302 /// }
303 /// }
304 /// ```
305 #[inline]
306 fn bound(&mut self, max: u64) -> u64 {
307 // Lemire's nearly divisionless method: https://arxiv.org/abs/1805.10941.
308 let (mut high, mut low) = util::wide_mul(self.u64(), max);
309 match low < max {
310 false => {
311 // TODO: Use the `unlikely` hint when it get stabilized
312 // to indicate this branch is unlikely.
313 }
314 true => {
315 // The dreaded division.
316 let threshold = max.wrapping_neg() % max;
317 while low < threshold {
318 (high, low) = util::wide_mul(self.u64(), max);
319 }
320 }
321 }
322 debug_assert!(
323 (max != 0 && high < max) || high == 0,
324 "BUG: assertion should be unreachable"
325 );
326 high
327 }
328
329 /// Returns a uniformly distributed `u64` in the interval \[0, `max`\].
330 ///
331 /// It is expected that `max` != `u64::MAX`.
332 ///
333 /// # Examples
334 ///
335 /// ```
336 /// use ya_rand::*;
337 ///
338 /// let mut rng = new_rng();
339 /// for i in 0..=2000 {
340 /// for _ in 0..(i * 2) {
341 /// assert!(rng.bound_inclusive(i) <= i);
342 /// }
343 /// }
344 /// ```
345 #[inline]
346 fn bound_inclusive(&mut self, max: u64) -> u64 {
347 self.bound(max + 1)
348 }
349
350 /// Returns a uniformly distributed `i64` in the interval [`min`, `max`)
351 ///
352 /// It is expected that `min` < `max`.
353 #[inline]
354 fn range(&mut self, min: i64, max: i64) -> i64 {
355 let delta = max.abs_diff(min);
356 (self.bound(delta) as i64) + min
357 }
358
359 /// Returns a uniformly distributed `i64` in the interval \[`min`, `max`\]
360 ///
361 /// It is expected that `min` <= `max` and `max` != `i64::MAX`.
362 #[inline]
363 fn range_inclusive(&mut self, min: i64, max: i64) -> i64 {
364 self.range(min, max + 1)
365 }
366
367 /// Returns a uniformly distributed `f64` in the interval [0.0, 1.0).
368 #[inline]
369 fn f64(&mut self) -> f64 {
370 self.bits(F64_MANT) as f64 / F64_DIVISOR
371 }
372
373 /// Returns a uniformly distributed `f32` in the interval [0.0, 1.0).
374 #[inline]
375 fn f32(&mut self) -> f32 {
376 self.bits(F32_MANT) as f32 / F32_DIVISOR
377 }
378
379 /// Returns a uniformly distributed `f64` in the interval (0.0, 1.0].
380 #[inline]
381 fn f64_nonzero(&mut self) -> f64 {
382 // Interval of (0, 2^53]
383 let nonzero = self.bits(F64_MANT) + 1;
384 nonzero as f64 / F64_DIVISOR
385 }
386
387 /// Returns a uniformly distributed `f32` in the interval (0.0, 1.0].
388 #[inline]
389 fn f32_nonzero(&mut self) -> f32 {
390 // Interval of (0, 2^24]
391 let nonzero = self.bits(F32_MANT) + 1;
392 nonzero as f32 / F32_DIVISOR
393 }
394
395 /// Returns a uniformly distributed `f64` in the interval (-1.0, 1.0).
396 #[inline]
397 fn f64_wide(&mut self) -> f64 {
398 // This approach is faster than using Generator::range.
399 const BITS: u32 = F64_MANT + 1;
400 const OFFSET: i64 = F64_MAX_PRECISE as i64;
401 let mut x: i64;
402 loop {
403 // Start with an interval of [0, 2^54)
404 x = self.bits(BITS) as i64;
405 // Interval is now (0, 2^54)
406 if x != 0 {
407 break;
408 }
409 }
410 // Shift interval to (-2^53, 2^53)
411 x -= OFFSET;
412 x as f64 / F64_DIVISOR
413 }
414
415 /// Returns a uniformly distributed `f32` in the interval (-1.0, 1.0).
416 #[inline]
417 fn f32_wide(&mut self) -> f32 {
418 // This approach is faster than using Generator::range.
419 const BITS: u32 = F32_MANT + 1;
420 const OFFSET: i64 = F32_MAX_PRECISE as i64;
421 let mut x: i64;
422 loop {
423 // Start with an interval of [0, 2^25)
424 x = self.bits(BITS) as i64;
425 // Interval is now (0, 2^25)
426 if x != 0 {
427 break;
428 }
429 }
430 // Shift interval to (-2^24, 2^24)
431 x -= OFFSET;
432 x as f32 / F32_DIVISOR
433 }
434
435 /// Returns two indepedent and normally distributed `f64` values with
436 /// a `mean` of `0.0` and a `stddev` of `1.0`.
437 #[cfg(feature = "std")]
438 fn f64_normal(&mut self) -> (f64, f64) {
439 // Marsaglia polar method.
440 // TLDR: It projects a point within the unit
441 // circle onto the unit radius.
442 let mut x: f64;
443 let mut y: f64;
444 let mut s: f64;
445 loop {
446 x = self.f64_wide();
447 y = self.f64_wide();
448 s = (x * x) + (y * y);
449 // Reroll if `s` does not lie **within** the unit circle.
450 if s < 1.0 && s != 0.0 {
451 break;
452 }
453 }
454 let t = (2.0 * s.ln().abs() / s).sqrt();
455 (x * t, y * t)
456 }
457
458 /// Returns two indepedent and normally distributed `f64` values with
459 /// user-defined `mean` and `stddev`.
460 ///
461 /// It is expected that `stddev.abs()` != `0.0`.
462 #[cfg(feature = "std")]
463 #[inline]
464 fn f64_normal_distribution(&mut self, mean: f64, stddev: f64) -> (f64, f64) {
465 let (x, y) = self.f64_normal();
466 let x_adjusted = x.mul_add(stddev, mean);
467 let y_adjusted = y.mul_add(stddev, mean);
468 (x_adjusted, y_adjusted)
469 }
470
471 /// Returns an exponentially distributed `f64` with a `lambda` of `1.0`.
472 #[cfg(feature = "std")]
473 #[inline]
474 fn f64_exponential(&mut self) -> f64 {
475 // Using abs() instead of negating the result of ln() to
476 // eliminate the possibility of ever returning -0.0.
477 self.f64_nonzero().ln().abs()
478 }
479
480 /// Returns an exponentially distributed `f64` with user-defined `lambda`.
481 ///
482 /// It is expected that `lambda.abs()` != `0.0`.
483 #[cfg(feature = "std")]
484 #[inline]
485 fn f64_exponential_lambda(&mut self, lambda: f64) -> f64 {
486 self.f64_exponential() / lambda
487 }
488
489 /// Returns a randomly chosen item from the iterator of `collection`.
490 ///
491 /// Returns `None` when the length of the iterator is zero.
492 ///
493 /// # Examples
494 ///
495 /// ```
496 /// use ya_rand::*;
497 ///
498 /// const SIZE: usize = 1738;
499 /// let mut rng = new_rng();
500 /// let mut v = [0; SIZE];
501 /// for i in 0..SIZE {
502 /// v[i] = i;
503 /// }
504 /// let (top, bottom) = v.split_at(v.len() / 2);
505 ///
506 /// // Sanity check.
507 /// let random_item = rng.choose(&v).expect("vector `v` is not empty");
508 /// assert!(v.contains(random_item) == true);
509 ///
510 /// // Choose `random_item` from the top half of the array.
511 /// let random_item = rng.choose(top).expect("still not empty");
512 /// assert!(top.contains(random_item) == true);
513 ///
514 /// // We're looking in the bottom half so we won't find the
515 /// // `random_item` from the top half.
516 /// assert!(bottom.contains(random_item) == false);
517 /// ```
518 #[inline]
519 fn choose<C>(&mut self, collection: C) -> Option<C::Item>
520 where
521 C: IntoIterator,
522 C::IntoIter: ExactSizeIterator,
523 {
524 let mut iter = collection.into_iter();
525 let len = iter.len();
526 match len != 0 {
527 true => Some({
528 let idx = self.bound(len as u64) as usize;
529 // SAFETY: Since `bound` always returns a value less than
530 // it's input, `nth` will never return `None`.
531 unsafe { iter.nth(idx).unwrap_unchecked() }
532 }),
533 false => None,
534 }
535 }
536
537 /// Returns a randomly selected ASCII character from the pool of:
538 ///
539 /// `'A'..='Z'`, and`'a'..='z'`
540 #[inline]
541 fn ascii_alphabetic(&mut self) -> char {
542 *self.choose(&ALPHANUMERIC[..52]).unwrap() as char
543 }
544
545 /// Returns a randomly selected ASCII character from the pool of:
546 ///
547 /// `'A'..='Z'`
548 #[inline]
549 fn ascii_uppercase(&mut self) -> char {
550 *self.choose(&ALPHANUMERIC[..26]).unwrap() as char
551 }
552
553 /// Returns a randomly selected ASCII character from the pool of:
554 ///
555 /// `'a'..='z'`
556 #[inline]
557 fn ascii_lowercase(&mut self) -> char {
558 *self.choose(&ALPHANUMERIC[26..52]).unwrap() as char
559 }
560
561 /// Returns a randomly selected ASCII character from the pool of:
562 ///
563 /// `'A'..='Z'`, `'a'..='z'`, and `'0'..='9'`
564 #[inline]
565 fn ascii_alphanumeric(&mut self) -> char {
566 *self.choose(&ALPHANUMERIC[..]).unwrap() as char
567 }
568
569 /// Returns a randomly selected ASCII character from the pool of:
570 ///
571 /// `'0'..='9'`
572 #[inline]
573 fn ascii_digit(&mut self) -> char {
574 *self.choose(&ALPHANUMERIC[52..]).unwrap() as char
575 }
576
577 /// Performs a Fisher-Yates shuffle on the contents of `slice`.
578 ///
579 /// This implementation is the modern variant introduced by
580 /// Richard Durstenfeld. It is in-place and O(n).
581 ///
582 /// # Examples
583 ///
584 /// ```
585 /// use ya_rand::*;
586 ///
587 /// let mut rng = new_rng();
588 /// let mut data = [0; 1738];
589 /// for i in 0..data.len() {
590 /// data[i] = i;
591 /// }
592 /// assert!(data.is_sorted() == true);
593 ///
594 /// rng.shuffle(&mut data);
595 /// assert!(data.is_sorted() == false);
596 /// ```
597 #[inline(never)]
598 fn shuffle<T>(&mut self, slice: &mut [T]) {
599 let slice_ptr = slice.as_mut_ptr();
600 for i in (1..slice.len()).rev() {
601 let j = self.bound_inclusive(i as u64) as usize;
602 // SAFETY: Index 'i' will always be in bounds because it's
603 // bounded by slice length; index 'j' will always be
604 // in bounds because it's bounded by 'i'.
605 unsafe {
606 ptr::swap(slice_ptr.add(i), slice_ptr.add(j));
607 }
608 }
609 }
610
611 /// Clones `slice` into a new `Vec`, calls [`Generator::shuffle`]
612 /// on it, and returns the result.
613 #[cfg(all(feature = "alloc", feature = "secure"))]
614 #[inline]
615 fn shuffle_cloned<T: Clone>(&mut self, slice: &[T]) -> Vec<T> {
616 let mut v = slice.to_vec();
617 self.shuffle(&mut v);
618 v
619 }
620}