nanorand/
rand.rs

1#[cfg(feature = "chacha")]
2pub use chacha::{ChaCha, ChaCha12, ChaCha20, ChaCha8};
3#[cfg(feature = "pcg64")]
4pub use pcg64::Pcg64;
5#[cfg(feature = "wyrand")]
6pub use wyrand::WyRand;
7
8use crate::gen::{RandomGen, RandomRange};
9use core::ops::RangeBounds;
10
11/// Implementation of the wyrand PRNG algorithm.
12/// More details can be seen at <https://github.com/wangyi-fudan/wyhash>
13#[cfg(feature = "wyrand")]
14pub mod wyrand;
15
16/// Implementation of the Pcg64 PRNG algorithm.
17/// More details can be seen at <https://www.pcg-random.org/index.html>
18#[cfg(feature = "pcg64")]
19pub mod pcg64;
20
21/// Implementation of the ChaCha CSPRNG algorithm.
22/// More details can be seen at <https://en.wikipedia.org/wiki/Salsa20>
23#[cfg(feature = "chacha")]
24pub mod chacha;
25
26/// A trait that represents a random number generator.
27pub trait Rng<const OUTPUT: usize>: Clone {
28	/// Generates a random sequence of bytes, seeding from the internal state.
29	fn rand(&mut self) -> [u8; OUTPUT];
30	/// Generates a random of the specified type, seeding from the internal state.
31	fn generate<Generated>(&mut self) -> Generated
32	where
33		Generated: RandomGen<Self, OUTPUT>,
34	{
35		Generated::random(self)
36	}
37	/// Fill an array of bytes with randomness.
38	fn fill_bytes<Bytes>(&mut self, mut buffer: Bytes)
39	where
40		Bytes: AsMut<[u8]>,
41	{
42		let mut buffer = buffer.as_mut();
43		let mut length = buffer.len();
44		while length > 0 {
45			let chunk = self.rand();
46			let generated = chunk.len().min(length);
47			buffer[..generated].copy_from_slice(&chunk[..generated]);
48			buffer = &mut buffer[generated..];
49			length -= generated;
50		}
51	}
52	/// Fill an array with the specified type.
53	fn fill<Contents, Array>(&mut self, mut target: Array)
54	where
55		Contents: RandomGen<Self, OUTPUT>,
56		Array: AsMut<[Contents]>,
57	{
58		let target = target.as_mut();
59		target.iter_mut().for_each(|entry| *entry = self.generate());
60	}
61	/// Generates a random of the specified type, seeding from the internal state.
62	fn generate_range<Number, Bounds>(&mut self, range: Bounds) -> Number
63	where
64		Number: RandomRange<Self, OUTPUT>,
65		Bounds: RangeBounds<Number>,
66	{
67		Number::random_range(self, range)
68	}
69	/// Shuffle a slice, using the RNG.
70	fn shuffle<Contents, Array>(&mut self, mut target: Array)
71	where
72		Array: AsMut<[Contents]>,
73	{
74		let target = target.as_mut();
75		let target_len = target.len();
76		for idx in 0..target_len {
77			let random_idx = self.generate_range(0..target_len);
78			target.swap(idx, random_idx);
79		}
80	}
81}
82
83/// A trait that represents an RNG that can be reseeded from arbitrary bytes.
84pub trait SeedableRng<const SEED_SIZE: usize, const OUTPUT: usize>: Rng<OUTPUT> {
85	/// Re-seed the RNG with the specified bytes.
86	fn reseed(&mut self, seed: [u8; SEED_SIZE]);
87}