Coverage Report

Created: 2026-05-23 06:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/rand-0.10.1/src/lib.rs
Line
Count
Source
1
// Copyright 2018 Developers of the Rand project.
2
// Copyright 2013-2017 The Rust Project Developers.
3
//
4
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
7
// option. This file may not be copied, modified, or distributed
8
// except according to those terms.
9
10
//! Utilities for random number generation
11
//!
12
//! Rand provides utilities to generate random numbers, to convert them to
13
//! useful types and distributions, and some randomness-related algorithms.
14
//!
15
//! # Quick Start
16
//!
17
//! ```
18
//! // The prelude import enables methods we use below, specifically
19
//! // Rng::random, Rng::sample, SliceRandom::shuffle and IndexedRandom::choose.
20
//! use rand::prelude::*;
21
//!
22
//! // Get an RNG:
23
//! let mut rng = rand::rng();
24
//!
25
//! // Try printing a random unicode code point (probably a bad idea)!
26
//! println!("char: '{}'", rng.random::<char>());
27
//! // Try printing a random alphanumeric value instead!
28
//! println!("alpha: '{}'", rng.sample(rand::distr::Alphanumeric) as char);
29
//!
30
//! // Generate and shuffle a sequence:
31
//! let mut nums: Vec<i32> = (1..100).collect();
32
//! nums.shuffle(&mut rng);
33
//! // And take a random pick (yes, we didn't need to shuffle first!):
34
//! let _ = nums.choose(&mut rng);
35
//! ```
36
//!
37
//! # The Book
38
//!
39
//! For the user guide and further documentation, please read
40
//! [The Rust Rand Book](https://rust-random.github.io/book).
41
42
#![doc(
43
    html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
44
    html_favicon_url = "https://www.rust-lang.org/favicon.ico"
45
)]
46
#![deny(missing_docs)]
47
#![deny(missing_debug_implementations)]
48
#![doc(test(attr(allow(unused_variables), deny(warnings))))]
49
#![no_std]
50
#![cfg_attr(feature = "simd_support", feature(portable_simd))]
51
#![cfg_attr(
52
    all(feature = "simd_support", target_feature = "avx512bw"),
53
    feature(stdarch_x86_avx512)
54
)]
55
#![cfg_attr(docsrs, feature(doc_cfg))]
56
#![allow(
57
    clippy::float_cmp,
58
    clippy::neg_cmp_op_on_partial_ord,
59
    clippy::nonminimal_bool
60
)]
61
#![deny(clippy::undocumented_unsafe_blocks)]
62
63
#[cfg(feature = "alloc")]
64
extern crate alloc;
65
#[cfg(feature = "std")]
66
extern crate std;
67
68
// Re-export rand_core itself
69
pub use rand_core;
70
71
// Re-exports from rand_core
72
pub use rand_core::{CryptoRng, Rng, SeedableRng, TryCryptoRng, TryRng};
73
74
// Public modules
75
pub mod distr;
76
pub mod prelude;
77
mod rng;
78
pub mod rngs;
79
pub mod seq;
80
81
// Public exports
82
#[cfg(feature = "thread_rng")]
83
pub use crate::rngs::thread::rng;
84
85
pub use rng::{Fill, RngExt};
86
87
#[cfg(feature = "thread_rng")]
88
use crate::distr::{Distribution, StandardUniform};
89
90
/// Construct and seed an RNG
91
///
92
/// This method yields a seeded RNG, using [`rng`] ([`ThreadRng`]) if enabled or
93
/// [`SysRng`] otherwise.
94
///
95
/// # Examples
96
///
97
/// ```
98
/// let mut rng: rand::rngs::SmallRng = rand::make_rng();
99
/// # let _ = rand::Rng::next_u32(&mut rng);
100
/// ```
101
///
102
/// # Panics
103
///
104
/// If [`SysRng`] fails to obtain entropy from the OS. This is unlikely
105
/// outside of early boot or unusual system conditions.
106
///
107
/// # Security
108
///
109
/// Refer to [`ThreadRng#Security`].
110
///
111
/// [`SysRng`]: crate::rngs::SysRng
112
/// [`ThreadRng`]: crate::rngs::ThreadRng
113
/// [`ThreadRng#Security`]: crate::rngs::ThreadRng#security
114
#[cfg(feature = "sys_rng")]
115
#[track_caller]
116
0
pub fn make_rng<R: SeedableRng>() -> R {
117
    #[cfg(feature = "thread_rng")]
118
    {
119
0
        R::from_rng(&mut rng())
120
    }
121
122
    #[cfg(not(feature = "thread_rng"))]
123
    {
124
        R::try_from_rng(&mut rngs::SysRng).expect("unexpected failure from SysRng")
125
    }
126
0
}
127
128
/// Adapter to support [`std::io::Read`] over a [`TryRng`]
129
///
130
/// # Examples
131
///
132
/// ```no_run
133
/// use std::{io, io::Read};
134
/// use std::fs::File;
135
/// use rand::{rngs::SysRng, RngReader};
136
///
137
/// io::copy(
138
///     &mut RngReader(SysRng).take(100),
139
///     &mut File::create("/tmp/random.bytes").unwrap()
140
/// ).unwrap();
141
/// ```
142
#[cfg(feature = "std")]
143
pub struct RngReader<R: TryRng>(pub R);
144
145
#[cfg(feature = "std")]
146
impl<R: TryRng> std::io::Read for RngReader<R> {
147
    #[inline]
148
0
    fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
149
0
        self.0
150
0
            .try_fill_bytes(buf)
151
0
            .map_err(|err| std::io::Error::other(std::format!("RNG error: {err}")))?;
152
0
        Ok(buf.len())
153
0
    }
154
}
155
156
#[cfg(feature = "std")]
157
impl<R: TryRng> std::fmt::Debug for RngReader<R> {
158
0
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
159
0
        f.debug_tuple("RngReader").finish()
160
0
    }
161
}
162
163
/// Generate a random value using the thread-local random number generator.
164
///
165
/// This function is shorthand for <code>[rng()].[random()](RngExt::random)</code>:
166
///
167
/// -   See [`ThreadRng`] for documentation of the generator and security
168
/// -   See [`StandardUniform`] for documentation of supported types and distributions
169
///
170
/// # Examples
171
///
172
/// ```
173
/// let x = rand::random::<u8>();
174
/// println!("{}", x);
175
///
176
/// let y = rand::random::<f64>();
177
/// println!("{}", y);
178
///
179
/// if rand::random() { // generates a boolean
180
///     println!("Better lucky than good!");
181
/// }
182
/// ```
183
///
184
/// If you're calling `random()` repeatedly, consider using a local `rng`
185
/// handle to save an initialization-check on each usage:
186
///
187
/// ```
188
/// use rand::RngExt; // provides the `random` method
189
///
190
/// let mut rng = rand::rng(); // a local handle to the generator
191
///
192
/// let mut v = vec![1, 2, 3];
193
///
194
/// for x in v.iter_mut() {
195
///     *x = rng.random();
196
/// }
197
/// ```
198
///
199
/// [`StandardUniform`]: distr::StandardUniform
200
/// [`ThreadRng`]: rngs::ThreadRng
201
#[cfg(feature = "thread_rng")]
202
#[inline]
203
0
pub fn random<T>() -> T
204
0
where
205
0
    StandardUniform: Distribution<T>,
206
{
207
0
    rng().random()
208
0
}
Unexecuted instantiation: rand::random::<u32>
Unexecuted instantiation: rand::random::<u16>
Unexecuted instantiation: rand::random::<_>
209
210
/// Return an iterator over [`random()`] variates
211
///
212
/// This function is shorthand for
213
/// <code>[rng()].[random_iter](RngExt::random_iter)()</code>.
214
///
215
/// # Example
216
///
217
/// ```
218
/// let v: Vec<i32> = rand::random_iter().take(5).collect();
219
/// println!("{v:?}");
220
/// ```
221
#[cfg(feature = "thread_rng")]
222
#[inline]
223
0
pub fn random_iter<T>() -> distr::Iter<StandardUniform, rngs::ThreadRng, T>
224
0
where
225
0
    StandardUniform: Distribution<T>,
226
{
227
0
    rng().random_iter()
228
0
}
229
230
/// Generate a random value in the given range using the thread-local random number generator.
231
///
232
/// This function is shorthand for
233
/// <code>[rng()].[random_range](RngExt::random_range)(<var>range</var>)</code>.
234
///
235
/// # Example
236
///
237
/// ```
238
/// let y: f32 = rand::random_range(0.0..=1e9);
239
/// println!("{}", y);
240
///
241
/// let words: Vec<&str> = "Mary had a little lamb".split(' ').collect();
242
/// println!("{}", words[rand::random_range(..words.len())]);
243
/// ```
244
/// Note that the second example can also be achieved (without `collect`'ing
245
/// to a `Vec`) using [`seq::IteratorRandom::choose`].
246
#[cfg(feature = "thread_rng")]
247
#[inline]
248
0
pub fn random_range<T, R>(range: R) -> T
249
0
where
250
0
    T: distr::uniform::SampleUniform,
251
0
    R: distr::uniform::SampleRange<T>,
252
{
253
0
    rng().random_range(range)
254
0
}
255
256
/// Return a bool with a probability `p` of being true.
257
///
258
/// This function is shorthand for
259
/// <code>[rng()].[random_bool](RngExt::random_bool)(<var>p</var>)</code>.
260
///
261
/// # Example
262
///
263
/// ```
264
/// println!("{}", rand::random_bool(1.0 / 3.0));
265
/// ```
266
///
267
/// # Panics
268
///
269
/// If `p < 0` or `p > 1`.
270
#[cfg(feature = "thread_rng")]
271
#[inline]
272
#[track_caller]
273
0
pub fn random_bool(p: f64) -> bool {
274
0
    rng().random_bool(p)
275
0
}
276
277
/// Return a bool with a probability of `numerator/denominator` of being
278
/// true.
279
///
280
/// That is, `random_ratio(2, 3)` has chance of 2 in 3, or about 67%, of
281
/// returning true. If `numerator == denominator`, then the returned value
282
/// is guaranteed to be `true`. If `numerator == 0`, then the returned
283
/// value is guaranteed to be `false`.
284
///
285
/// See also the [`Bernoulli`] distribution, which may be faster if
286
/// sampling from the same `numerator` and `denominator` repeatedly.
287
///
288
/// This function is shorthand for
289
/// <code>[rng()].[random_ratio](RngExt::random_ratio)(<var>numerator</var>, <var>denominator</var>)</code>.
290
///
291
/// # Panics
292
///
293
/// If `denominator == 0` or `numerator > denominator`.
294
///
295
/// # Example
296
///
297
/// ```
298
/// println!("{}", rand::random_ratio(2, 3));
299
/// ```
300
///
301
/// [`Bernoulli`]: distr::Bernoulli
302
#[cfg(feature = "thread_rng")]
303
#[inline]
304
#[track_caller]
305
0
pub fn random_ratio(numerator: u32, denominator: u32) -> bool {
306
0
    rng().random_ratio(numerator, denominator)
307
0
}
308
309
/// Fill any type implementing [`Fill`] with random data
310
///
311
/// This function is shorthand for
312
/// <code>[rng()].[fill](RngExt::fill)(<var>dest</var>)</code>.
313
///
314
/// # Example
315
///
316
/// ```
317
/// let mut arr = [0i8; 20];
318
/// rand::fill(&mut arr[..]);
319
/// ```
320
///
321
/// Note that you can instead use [`random()`] to generate an array of random
322
/// data, though this is slower for small elements (smaller than the RNG word
323
/// size).
324
#[cfg(feature = "thread_rng")]
325
#[inline]
326
#[track_caller]
327
0
pub fn fill<T: Fill>(dest: &mut [T]) {
328
0
    Fill::fill_slice(dest, &mut rng())
329
0
}
330
331
#[cfg(test)]
332
mod test {
333
    use super::*;
334
    use core::convert::Infallible;
335
336
    /// Construct a deterministic RNG with the given seed
337
    pub fn rng(seed: u64) -> impl Rng {
338
        // For tests, we want a statistically good, fast, reproducible RNG.
339
        // PCG32 will do fine, and will be easy to embed if we ever need to.
340
        const INC: u64 = 11634580027462260723;
341
        rand_pcg::Pcg32::new(seed, INC)
342
    }
343
344
    /// Construct a generator yielding a constant value
345
    pub fn const_rng(x: u64) -> StepRng {
346
        StepRng(x, 0)
347
    }
348
349
    /// Construct a generator yielding an arithmetic sequence
350
    pub fn step_rng(x: u64, increment: u64) -> StepRng {
351
        StepRng(x, increment)
352
    }
353
354
    #[derive(Clone)]
355
    pub struct StepRng(u64, u64);
356
    impl TryRng for StepRng {
357
        type Error = Infallible;
358
359
        fn try_next_u32(&mut self) -> Result<u32, Infallible> {
360
            self.try_next_u64().map(|x| x as u32)
361
        }
362
363
        fn try_next_u64(&mut self) -> Result<u64, Infallible> {
364
            let res = self.0;
365
            self.0 = self.0.wrapping_add(self.1);
366
            Ok(res)
367
        }
368
369
        fn try_fill_bytes(&mut self, dst: &mut [u8]) -> Result<(), Infallible> {
370
            rand_core::utils::fill_bytes_via_next_word(dst, || self.try_next_u64())
371
        }
372
    }
373
374
    #[cfg(feature = "std")]
375
    #[test]
376
    fn rng_reader() {
377
        use std::io::Read;
378
379
        let mut rng = StepRng(255, 1);
380
        let mut buf = [0u8; 24];
381
        let expected = [
382
            255, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,
383
        ];
384
385
        RngReader(&mut rng).read_exact(&mut buf).unwrap();
386
        assert_eq!(&buf, &expected);
387
388
        RngReader(StepRng(255, 1)).read_exact(&mut buf).unwrap();
389
        assert_eq!(&buf, &expected);
390
    }
391
392
    #[test]
393
    #[cfg(feature = "thread_rng")]
394
    fn test_random() {
395
        let _n: u64 = random();
396
        let _f: f32 = random();
397
        #[allow(clippy::type_complexity)]
398
        let _many: (
399
            (),
400
            [(u32, bool); 3],
401
            (u8, i8, u16, i16, u32, i32, u64, i64),
402
            (f32, (f64, (f64,))),
403
        ) = random();
404
    }
405
406
    #[test]
407
    #[cfg(feature = "thread_rng")]
408
    fn test_range() {
409
        let _n: usize = random_range(42..=43);
410
        let _f: f32 = random_range(42.0..43.0);
411
    }
412
}