rand/
lib.rs

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    html_root_url = "https://rust-random.github.io/rand/"
46)]
47#![deny(missing_docs)]
48#![deny(missing_debug_implementations)]
49#![doc(test(attr(allow(unused_variables), deny(warnings))))]
50#![no_std]
51#![cfg_attr(feature = "simd_support", feature(portable_simd))]
52#![cfg_attr(
53    all(feature = "simd_support", target_feature = "avx512bw"),
54    feature(stdarch_x86_avx512)
55)]
56#![cfg_attr(docsrs, feature(doc_cfg))]
57#![allow(
58    clippy::float_cmp,
59    clippy::neg_cmp_op_on_partial_ord,
60    clippy::nonminimal_bool
61)]
62#![deny(clippy::undocumented_unsafe_blocks)]
63
64#[cfg(feature = "alloc")]
65extern crate alloc;
66#[cfg(feature = "std")]
67extern crate std;
68
69#[allow(unused)]
70macro_rules! trace { ($($x:tt)*) => (
71    #[cfg(feature = "log")] {
72        log::trace!($($x)*)
73    }
74) }
75#[allow(unused)]
76macro_rules! debug { ($($x:tt)*) => (
77    #[cfg(feature = "log")] {
78        log::debug!($($x)*)
79    }
80) }
81#[allow(unused)]
82macro_rules! info { ($($x:tt)*) => (
83    #[cfg(feature = "log")] {
84        log::info!($($x)*)
85    }
86) }
87#[allow(unused)]
88macro_rules! warn { ($($x:tt)*) => (
89    #[cfg(feature = "log")] {
90        log::warn!($($x)*)
91    }
92) }
93#[allow(unused)]
94macro_rules! error { ($($x:tt)*) => (
95    #[cfg(feature = "log")] {
96        log::error!($($x)*)
97    }
98) }
99
100// Re-export rand_core itself
101pub use rand_core;
102
103// Re-exports from rand_core
104pub use rand_core::{CryptoRng, RngCore, SeedableRng, TryCryptoRng, TryRngCore};
105
106// Public modules
107pub mod distr;
108pub mod prelude;
109mod rng;
110pub mod rngs;
111pub mod seq;
112
113// Public exports
114#[cfg(feature = "thread_rng")]
115pub use crate::rngs::thread::rng;
116
117/// Access the thread-local generator
118///
119/// Use [`rand::rng()`](rng()) instead.
120#[cfg(feature = "thread_rng")]
121#[deprecated(since = "0.9.0", note = "Renamed to `rng`")]
122#[inline]
123pub fn thread_rng() -> crate::rngs::ThreadRng {
124    rng()
125}
126
127pub use rng::{Fill, Rng};
128
129#[cfg(feature = "thread_rng")]
130use crate::distr::{Distribution, StandardUniform};
131
132/// Adapter to support [`std::io::Read`] over a [`TryRngCore`]
133///
134/// # Examples
135///
136/// ```no_run
137/// use std::{io, io::Read};
138/// use std::fs::File;
139/// use rand::{rngs::OsRng, RngReader};
140///
141/// io::copy(
142///     &mut RngReader(OsRng).take(100),
143///     &mut File::create("/tmp/random.bytes").unwrap()
144/// ).unwrap();
145/// ```
146#[cfg(feature = "std")]
147pub struct RngReader<R: TryRngCore>(pub R);
148
149#[cfg(feature = "std")]
150impl<R: TryRngCore> std::io::Read for RngReader<R> {
151    #[inline]
152    fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
153        self.0
154            .try_fill_bytes(buf)
155            .map_err(|err| std::io::Error::other(std::format!("RNG error: {err}")))?;
156        Ok(buf.len())
157    }
158}
159
160#[cfg(feature = "std")]
161impl<R: TryRngCore> std::fmt::Debug for RngReader<R> {
162    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
163        f.debug_tuple("RngReader").finish()
164    }
165}
166
167/// Generate a random value using the thread-local random number generator.
168///
169/// This function is shorthand for <code>[rng()].[random()](Rng::random)</code>:
170///
171/// -   See [`ThreadRng`] for documentation of the generator and security
172/// -   See [`StandardUniform`] for documentation of supported types and distributions
173///
174/// # Examples
175///
176/// ```
177/// let x = rand::random::<u8>();
178/// println!("{}", x);
179///
180/// let y = rand::random::<f64>();
181/// println!("{}", y);
182///
183/// if rand::random() { // generates a boolean
184///     println!("Better lucky than good!");
185/// }
186/// ```
187///
188/// If you're calling `random()` repeatedly, consider using a local `rng`
189/// handle to save an initialization-check on each usage:
190///
191/// ```
192/// use rand::Rng; // provides the `random` method
193///
194/// let mut rng = rand::rng(); // a local handle to the generator
195///
196/// let mut v = vec![1, 2, 3];
197///
198/// for x in v.iter_mut() {
199///     *x = rng.random();
200/// }
201/// ```
202///
203/// [`StandardUniform`]: distr::StandardUniform
204/// [`ThreadRng`]: rngs::ThreadRng
205#[cfg(feature = "thread_rng")]
206#[inline]
207pub fn random<T>() -> T
208where
209    StandardUniform: Distribution<T>,
210{
211    rng().random()
212}
213
214/// Return an iterator over [`random()`] variates
215///
216/// This function is shorthand for
217/// <code>[rng()].[random_iter](Rng::random_iter)()</code>.
218///
219/// # Example
220///
221/// ```
222/// let v: Vec<i32> = rand::random_iter().take(5).collect();
223/// println!("{v:?}");
224/// ```
225#[cfg(feature = "thread_rng")]
226#[inline]
227pub fn random_iter<T>() -> distr::Iter<StandardUniform, rngs::ThreadRng, T>
228where
229    StandardUniform: Distribution<T>,
230{
231    rng().random_iter()
232}
233
234/// Generate a random value in the given range using the thread-local random number generator.
235///
236/// This function is shorthand for
237/// <code>[rng()].[random_range](Rng::random_range)(<var>range</var>)</code>.
238///
239/// # Example
240///
241/// ```
242/// let y: f32 = rand::random_range(0.0..=1e9);
243/// println!("{}", y);
244///
245/// let words: Vec<&str> = "Mary had a little lamb".split(' ').collect();
246/// println!("{}", words[rand::random_range(..words.len())]);
247/// ```
248/// Note that the first example can also be achieved (without `collect`'ing
249/// to a `Vec`) using [`seq::IteratorRandom::choose`].
250#[cfg(feature = "thread_rng")]
251#[inline]
252pub fn random_range<T, R>(range: R) -> T
253where
254    T: distr::uniform::SampleUniform,
255    R: distr::uniform::SampleRange<T>,
256{
257    rng().random_range(range)
258}
259
260/// Return a bool with a probability `p` of being true.
261///
262/// This function is shorthand for
263/// <code>[rng()].[random_bool](Rng::random_bool)(<var>p</var>)</code>.
264///
265/// # Example
266///
267/// ```
268/// println!("{}", rand::random_bool(1.0 / 3.0));
269/// ```
270///
271/// # Panics
272///
273/// If `p < 0` or `p > 1`.
274#[cfg(feature = "thread_rng")]
275#[inline]
276#[track_caller]
277pub fn random_bool(p: f64) -> bool {
278    rng().random_bool(p)
279}
280
281/// Return a bool with a probability of `numerator/denominator` of being
282/// true.
283///
284/// That is, `random_ratio(2, 3)` has chance of 2 in 3, or about 67%, of
285/// returning true. If `numerator == denominator`, then the returned value
286/// is guaranteed to be `true`. If `numerator == 0`, then the returned
287/// value is guaranteed to be `false`.
288///
289/// See also the [`Bernoulli`] distribution, which may be faster if
290/// sampling from the same `numerator` and `denominator` repeatedly.
291///
292/// This function is shorthand for
293/// <code>[rng()].[random_ratio](Rng::random_ratio)(<var>numerator</var>, <var>denominator</var>)</code>.
294///
295/// # Panics
296///
297/// If `denominator == 0` or `numerator > denominator`.
298///
299/// # Example
300///
301/// ```
302/// println!("{}", rand::random_ratio(2, 3));
303/// ```
304///
305/// [`Bernoulli`]: distr::Bernoulli
306#[cfg(feature = "thread_rng")]
307#[inline]
308#[track_caller]
309pub fn random_ratio(numerator: u32, denominator: u32) -> bool {
310    rng().random_ratio(numerator, denominator)
311}
312
313/// Fill any type implementing [`Fill`] with random data
314///
315/// This function is shorthand for
316/// <code>[rng()].[fill](Rng::fill)(<var>dest</var>)</code>.
317///
318/// # Example
319///
320/// ```
321/// let mut arr = [0i8; 20];
322/// rand::fill(&mut arr[..]);
323/// ```
324///
325/// Note that you can instead use [`random()`] to generate an array of random
326/// data, though this is slower for small elements (smaller than the RNG word
327/// size).
328#[cfg(feature = "thread_rng")]
329#[inline]
330#[track_caller]
331pub fn fill<T: Fill>(dest: &mut [T]) {
332    Fill::fill_slice(dest, &mut rng())
333}
334
335#[cfg(test)]
336mod test {
337    use super::*;
338
339    /// Construct a deterministic RNG with the given seed
340    pub fn rng(seed: u64) -> impl RngCore {
341        // For tests, we want a statistically good, fast, reproducible RNG.
342        // PCG32 will do fine, and will be easy to embed if we ever need to.
343        const INC: u64 = 11634580027462260723;
344        rand_pcg::Pcg32::new(seed, INC)
345    }
346
347    /// Construct a generator yielding a constant value
348    pub fn const_rng(x: u64) -> StepRng {
349        StepRng(x, 0)
350    }
351
352    /// Construct a generator yielding an arithmetic sequence
353    pub fn step_rng(x: u64, increment: u64) -> StepRng {
354        StepRng(x, increment)
355    }
356
357    #[derive(Clone)]
358    pub struct StepRng(u64, u64);
359    impl RngCore for StepRng {
360        fn next_u32(&mut self) -> u32 {
361            self.next_u64() as u32
362        }
363
364        fn next_u64(&mut self) -> u64 {
365            let res = self.0;
366            self.0 = self.0.wrapping_add(self.1);
367            res
368        }
369
370        fn fill_bytes(&mut self, dst: &mut [u8]) {
371            rand_core::le::fill_bytes_via_next(self, dst)
372        }
373    }
374
375    #[cfg(feature = "std")]
376    #[test]
377    fn rng_reader() {
378        use std::io::Read;
379
380        let mut rng = StepRng(255, 1);
381        let mut buf = [0u8; 24];
382        let expected = [
383            255, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,
384        ];
385
386        RngReader(&mut rng).read_exact(&mut buf).unwrap();
387        assert_eq!(&buf, &expected);
388
389        RngReader(StepRng(255, 1)).read_exact(&mut buf).unwrap();
390        assert_eq!(&buf, &expected);
391    }
392
393    #[test]
394    #[cfg(feature = "thread_rng")]
395    fn test_random() {
396        let _n: u64 = random();
397        let _f: f32 = random();
398        #[allow(clippy::type_complexity)]
399        let _many: (
400            (),
401            [(u32, bool); 3],
402            (u8, i8, u16, i16, u32, i32, u64, i64),
403            (f32, (f64, (f64,))),
404        ) = random();
405    }
406
407    #[test]
408    #[cfg(feature = "thread_rng")]
409    fn test_range() {
410        let _n: usize = random_range(42..=43);
411        let _f: f32 = random_range(42.0..43.0);
412    }
413}