/rust/registry/src/index.crates.io-1949cf8c6b5b557f/rand-0.9.2/src/rngs/small.rs
Line | Count | Source |
1 | | // Copyright 2018 Developers of the Rand project. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or |
4 | | // https://www.apache.org/licenses/LICENSE-2.0> or the MIT license |
5 | | // <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your |
6 | | // option. This file may not be copied, modified, or distributed |
7 | | // except according to those terms. |
8 | | |
9 | | //! A small fast RNG |
10 | | |
11 | | use rand_core::{RngCore, SeedableRng}; |
12 | | |
13 | | #[cfg(any(target_pointer_width = "32", target_pointer_width = "16"))] |
14 | | type Rng = super::xoshiro128plusplus::Xoshiro128PlusPlus; |
15 | | #[cfg(target_pointer_width = "64")] |
16 | | type Rng = super::xoshiro256plusplus::Xoshiro256PlusPlus; |
17 | | |
18 | | /// A small-state, fast, non-crypto, non-portable PRNG |
19 | | /// |
20 | | /// This is the "standard small" RNG, a generator with the following properties: |
21 | | /// |
22 | | /// - Non-[portable]: any future library version may replace the algorithm |
23 | | /// and results may be platform-dependent. |
24 | | /// (For a small portable generator, use the [rand_pcg] or [rand_xoshiro] crate.) |
25 | | /// - Non-cryptographic: output is easy to predict (insecure) |
26 | | /// - [Quality]: statistically good quality |
27 | | /// - Fast: the RNG is fast for both bulk generation and single values, with |
28 | | /// consistent cost of method calls |
29 | | /// - Fast initialization |
30 | | /// - Small state: little memory usage (current state size is 16-32 bytes |
31 | | /// depending on platform) |
32 | | /// |
33 | | /// The current algorithm is |
34 | | /// `Xoshiro256PlusPlus` on 64-bit platforms and `Xoshiro128PlusPlus` on 32-bit |
35 | | /// platforms. Both are also implemented by the [rand_xoshiro] crate. |
36 | | /// |
37 | | /// ## Seeding (construction) |
38 | | /// |
39 | | /// This generator implements the [`SeedableRng`] trait. All methods are |
40 | | /// suitable for seeding, but note that, even with a fixed seed, output is not |
41 | | /// [portable]. Some suggestions: |
42 | | /// |
43 | | /// 1. To automatically seed with a unique seed, use [`SeedableRng::from_rng`]: |
44 | | /// ``` |
45 | | /// use rand::SeedableRng; |
46 | | /// use rand::rngs::SmallRng; |
47 | | /// let rng = SmallRng::from_rng(&mut rand::rng()); |
48 | | /// # let _: SmallRng = rng; |
49 | | /// ``` |
50 | | /// or [`SeedableRng::from_os_rng`]: |
51 | | /// ``` |
52 | | /// # use rand::SeedableRng; |
53 | | /// # use rand::rngs::SmallRng; |
54 | | /// let rng = SmallRng::from_os_rng(); |
55 | | /// # let _: SmallRng = rng; |
56 | | /// ``` |
57 | | /// 2. To use a deterministic integral seed, use `seed_from_u64`. This uses a |
58 | | /// hash function internally to yield a (typically) good seed from any |
59 | | /// input. |
60 | | /// ``` |
61 | | /// # use rand::{SeedableRng, rngs::SmallRng}; |
62 | | /// let rng = SmallRng::seed_from_u64(1); |
63 | | /// # let _: SmallRng = rng; |
64 | | /// ``` |
65 | | /// 3. To seed deterministically from text or other input, use [`rand_seeder`]. |
66 | | /// |
67 | | /// See also [Seeding RNGs] in the book. |
68 | | /// |
69 | | /// ## Generation |
70 | | /// |
71 | | /// The generators implements [`RngCore`] and thus also [`Rng`][crate::Rng]. |
72 | | /// See also the [Random Values] chapter in the book. |
73 | | /// |
74 | | /// [portable]: https://rust-random.github.io/book/crate-reprod.html |
75 | | /// [Seeding RNGs]: https://rust-random.github.io/book/guide-seeding.html |
76 | | /// [Random Values]: https://rust-random.github.io/book/guide-values.html |
77 | | /// [Quality]: https://rust-random.github.io/book/guide-rngs.html#quality |
78 | | /// [`StdRng`]: crate::rngs::StdRng |
79 | | /// [rand_pcg]: https://crates.io/crates/rand_pcg |
80 | | /// [rand_xoshiro]: https://crates.io/crates/rand_xoshiro |
81 | | /// [`rand_chacha::ChaCha8Rng`]: https://docs.rs/rand_chacha/latest/rand_chacha/struct.ChaCha8Rng.html |
82 | | /// [`rand_seeder`]: https://docs.rs/rand_seeder/latest/rand_seeder/ |
83 | | #[derive(Clone, Debug, PartialEq, Eq)] |
84 | | pub struct SmallRng(Rng); |
85 | | |
86 | | impl SeedableRng for SmallRng { |
87 | | // Fix to 256 bits. Changing this is a breaking change! |
88 | | type Seed = [u8; 32]; |
89 | | |
90 | | #[inline(always)] |
91 | 0 | fn from_seed(seed: Self::Seed) -> Self { |
92 | | // This is for compatibility with 32-bit platforms where Rng::Seed has a different seed size |
93 | | // With MSRV >= 1.77: let seed = *seed.first_chunk().unwrap() |
94 | | const LEN: usize = core::mem::size_of::<<Rng as SeedableRng>::Seed>(); |
95 | 0 | let seed = (&seed[..LEN]).try_into().unwrap(); |
96 | 0 | SmallRng(Rng::from_seed(seed)) |
97 | 0 | } |
98 | | |
99 | | #[inline(always)] |
100 | 0 | fn seed_from_u64(state: u64) -> Self { |
101 | 0 | SmallRng(Rng::seed_from_u64(state)) |
102 | 0 | } |
103 | | } |
104 | | |
105 | | impl RngCore for SmallRng { |
106 | | #[inline(always)] |
107 | 0 | fn next_u32(&mut self) -> u32 { |
108 | 0 | self.0.next_u32() |
109 | 0 | } |
110 | | |
111 | | #[inline(always)] |
112 | 0 | fn next_u64(&mut self) -> u64 { |
113 | 0 | self.0.next_u64() |
114 | 0 | } |
115 | | |
116 | | #[inline(always)] |
117 | 0 | fn fill_bytes(&mut self, dest: &mut [u8]) { |
118 | 0 | self.0.fill_bytes(dest) |
119 | 0 | } |
120 | | } |