Coverage Report

Created: 2024-12-17 06:15

/rust/registry/src/index.crates.io-6f17d22bba15001f/rand-0.8.5/src/rngs/small.rs
Line
Count
Source (jump to first uncovered line)
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::{Error, RngCore, SeedableRng};
12
13
#[cfg(target_pointer_width = "64")]
14
type Rng = super::xoshiro256plusplus::Xoshiro256PlusPlus;
15
#[cfg(not(target_pointer_width = "64"))]
16
type Rng = super::xoshiro128plusplus::Xoshiro128PlusPlus;
17
18
/// A small-state, fast non-crypto PRNG
19
///
20
/// `SmallRng` may be a good choice when a PRNG with small state, cheap
21
/// initialization, good statistical quality and good performance are required.
22
/// Note that depending on the application, [`StdRng`] may be faster on many
23
/// modern platforms while providing higher-quality randomness. Furthermore,
24
/// `SmallRng` is **not** a good choice when:
25
/// - Security against prediction is important. Use [`StdRng`] instead.
26
/// - Seeds with many zeros are provided. In such cases, it takes `SmallRng`
27
///   about 10 samples to produce 0 and 1 bits with equal probability. Either
28
///   provide seeds with an approximately equal number of 0 and 1 (for example
29
///   by using [`SeedableRng::from_entropy`] or [`SeedableRng::seed_from_u64`]),
30
///   or use [`StdRng`] instead.
31
///
32
/// The algorithm is deterministic but should not be considered reproducible
33
/// due to dependence on platform and possible replacement in future
34
/// library versions. For a reproducible generator, use a named PRNG from an
35
/// external crate, e.g. [rand_xoshiro] or [rand_chacha].
36
/// Refer also to [The Book](https://rust-random.github.io/book/guide-rngs.html).
37
///
38
/// The PRNG algorithm in `SmallRng` is chosen to be efficient on the current
39
/// platform, without consideration for cryptography or security. The size of
40
/// its state is much smaller than [`StdRng`]. The current algorithm is
41
/// `Xoshiro256PlusPlus` on 64-bit platforms and `Xoshiro128PlusPlus` on 32-bit
42
/// platforms. Both are also implemented by the [rand_xoshiro] crate.
43
///
44
/// # Examples
45
///
46
/// Initializing `SmallRng` with a random seed can be done using [`SeedableRng::from_entropy`]:
47
///
48
/// ```
49
/// use rand::{Rng, SeedableRng};
50
/// use rand::rngs::SmallRng;
51
///
52
/// // Create small, cheap to initialize and fast RNG with a random seed.
53
/// // The randomness is supplied by the operating system.
54
/// let mut small_rng = SmallRng::from_entropy();
55
/// # let v: u32 = small_rng.gen();
56
/// ```
57
///
58
/// When initializing a lot of `SmallRng`'s, using [`thread_rng`] can be more
59
/// efficient:
60
///
61
/// ```
62
/// use rand::{SeedableRng, thread_rng};
63
/// use rand::rngs::SmallRng;
64
///
65
/// // Create a big, expensive to initialize and slower, but unpredictable RNG.
66
/// // This is cached and done only once per thread.
67
/// let mut thread_rng = thread_rng();
68
/// // Create small, cheap to initialize and fast RNGs with random seeds.
69
/// // One can generally assume this won't fail.
70
/// let rngs: Vec<SmallRng> = (0..10)
71
///     .map(|_| SmallRng::from_rng(&mut thread_rng).unwrap())
72
///     .collect();
73
/// ```
74
///
75
/// [`StdRng`]: crate::rngs::StdRng
76
/// [`thread_rng`]: crate::thread_rng
77
/// [rand_chacha]: https://crates.io/crates/rand_chacha
78
/// [rand_xoshiro]: https://crates.io/crates/rand_xoshiro
79
#[cfg_attr(doc_cfg, doc(cfg(feature = "small_rng")))]
80
#[derive(Clone, Debug, PartialEq, Eq)]
81
pub struct SmallRng(Rng);
82
83
impl RngCore for SmallRng {
84
    #[inline(always)]
85
0
    fn next_u32(&mut self) -> u32 {
86
0
        self.0.next_u32()
87
0
    }
88
89
    #[inline(always)]
90
0
    fn next_u64(&mut self) -> u64 {
91
0
        self.0.next_u64()
92
0
    }
93
94
    #[inline(always)]
95
0
    fn fill_bytes(&mut self, dest: &mut [u8]) {
96
0
        self.0.fill_bytes(dest);
97
0
    }
98
99
    #[inline(always)]
100
0
    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
101
0
        self.0.try_fill_bytes(dest)
102
0
    }
103
}
104
105
impl SeedableRng for SmallRng {
106
    type Seed = <Rng as SeedableRng>::Seed;
107
108
    #[inline(always)]
109
0
    fn from_seed(seed: Self::Seed) -> Self {
110
0
        SmallRng(Rng::from_seed(seed))
111
0
    }
112
113
    #[inline(always)]
114
0
    fn from_rng<R: RngCore>(rng: R) -> Result<Self, Error> {
115
0
        Rng::from_rng(rng).map(SmallRng)
116
0
    }
Unexecuted instantiation: <rand::rngs::small::SmallRng as rand_core::SeedableRng>::from_rng::<&mut rand::rngs::thread::ThreadRng>
Unexecuted instantiation: <rand::rngs::small::SmallRng as rand_core::SeedableRng>::from_rng::<&mut rand::rngs::thread::ThreadRng>
Unexecuted instantiation: <rand::rngs::small::SmallRng as rand_core::SeedableRng>::from_rng::<_>
117
}