Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 82 additions & 3 deletions library/std/src/random.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,52 @@
//! Random value generation.
//!
//! This module provides two low-level interfaces for random number generation:
//! * The [`Rng`] trait abstracts over all random number generators (RNGs) and
//! is intended to be used in all cases where the choice of RNG is left to the
//! user. It provides the [`fill_bytes`](Rng::fill_bytes) method that fills a
//! buffer of [`u8`]s with freshly-generated random data.
//! * The [`SystemRng`] implements the [`Rng`] trait by asking the operating
//! system for cryptographically-secure random data on every call to
//! `fill_bytes`.
//!
//! In the future, higher-level interfaces for features like sampling distributions
//! may be added to this module. Until that time, users of `fill_bytes` should
//! take care to avoid sampling bias when using the filled byte buffer to create
//! an instance of another type. In particular, the modulo operation is **not**
//! suitable for constraining the range of an unconstrained number:
//! ```compile_fail
//! let mut buf = [0; 2];
//! rng.fill_bytes(&mut buf);
//! // 💀 **DO NOT DO THIS** 💀
//! // Numbers below ca. 22000 will be twice as likely.
//! let very_bad_random_number = u16::from_ne_bytes(buf) % 45000;
//! ```
//!
//! # Examples
//!
//! Generating a [version 4/variant 1 UUID] represented as text:
//! ```
//! #![feature(random)]
//!
//! use std::random::{Rng, SystemRng};
//!
//! fn uuid(rng: &mut impl Rng) -> String {
//! let mut buf = [0; 16];
//! rng.fill_bytes(&mut buf);
//! // Use little-endian to make the result reproducible across architectures.
//! let bits = u128::from_le_bytes(buf);
//! let g1 = (bits >> 96) as u32;
//! let g2 = (bits >> 80) as u16;
//! let g3 = (0x4000 | (bits >> 64) & 0x0fff) as u16;
//! let g4 = (0x8000 | (bits >> 48) & 0x3fff) as u16;
//! let g5 = (bits & 0xffffffffffff) as u64;
//! format!("{g1:08x}-{g2:04x}-{g3:04x}-{g4:04x}-{g5:012x}")
//! }
//!
//! println!("{}", uuid(&mut SystemRng));
//! ```
//!
//! [version 4/variant 1 UUID]: https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)

#[unstable(feature = "random", issue = "130703")]
pub use core::random::*;
Expand All @@ -13,10 +61,28 @@ use crate::sys::random as sys;
///
/// The high quality of randomness provided by this source means it can be quite
/// slow on some targets. If you need a large quantity of random numbers and
/// security is not a concern, consider using an alternative random number
/// generator (potentially seeded from this one).
/// security is not a concern, you might want to consider using an alternative
/// random number generator. That said, `std` attempts to use the fastest source
/// available on the system that still provides strong security. A custom random
/// number generator will in nearly all cases have weaker security attributes
/// than `SystemRng`.
///
/// If you need to fill a buffer with random bytes, use `SystemRng.fill_bytes(&mut buf)`.
/// # Blocking
///
/// The underlying syscalls might block the calling thread until there is
/// sufficient [entropy] in the system to seed a procedural random number
/// generator. This is usually only a concern if the program runs immediately
/// after the system boots.
///
/// # Panicking
///
/// Calling `fill_bytes` will panic if the system cannot provide the required
/// random data. Due to the blocking behaviour described above, this is a
/// permanent condition in nearly all cases and implies that the system lacks
/// the facilities (hardware or software) necessary for collecting entropy.
/// Non-embedded systems usually do not suffer from this limitation.
///
/// [entropy]: https://en.wikipedia.org/wiki/Entropy_(information_theory)
///
/// # Underlying sources
///
Expand Down Expand Up @@ -59,6 +125,19 @@ use crate::sys::random as sys;
/// [`getrandom`]: https://www.man7.org/linux/man-pages/man2/getrandom.2.html
/// [`/dev/urandom`]: https://www.man7.org/linux/man-pages/man4/random.4.html
/// [`get-random-bytes`]: https://github.com/WebAssembly/WASI/blob/main/proposals/random/imports.md#get-random-bytes-func
///
/// # Examples
///
/// Filling a buffer with random bytes
/// ```
/// #![feature(random)]
///
/// use std::random::{Rng, SystemRng};
///
/// let mut buf = [0; 16];
/// SystemRng.fill_bytes(&mut buf);
/// dbg!(buf);
/// ```
#[doc(alias = "getrandom", alias = "getentropy", alias = "arc4random")]
#[derive(Default, Debug, Clone, Copy)]
#[unstable(feature = "random", issue = "130703")]
Expand Down
Loading