Random Values
Generate Random Numbers
This example demonstrates the basic usage of the rand
crate for generating random numbers :
//! In `Cargo.toml`, add: //! ```toml //! rand = { version = "0.9.0" } # Or latest. //! ``` fn main() { // Generate a random value:. let n1: u8 = rand::random(); println!("Random u8: {n1}"); // Use the "turbofish" notation to specify the type. // Integers are uniformly distributed over the range of the type: println!("Random u16: {}", rand::random::<u16>()); println!("Random u32: {}", rand::random::<u32>()); // Floating point numbers are uniformly distributed from 0 up to but not // including 1: println!("Random float: {}", rand::random::<f64>()); // Generate a boolean. Consider the `random_bool` function as well. if rand::random() { println!("Lucky!"); } // `random()` is a shorthand for `rng().random()`, where `rng()` returns // a handle to the local `ThreadRng`, a lazily-initialized thread-local // generator. }
Generate Random Numbers Within a Range
This example generates a random value within the half-open [0, 10)
range (not including 10
):
use rand::Rng; /// Demonstrates generating random numbers within a specified range. fn main() { // Obtain a random number generator: let mut rng = rand::rng(); // Generate a random integer between 0 (inclusive) and 10 (exclusive): println!("Integer: {}", rng.random_range(0..10)); // Generate a random float between 0.0 (inclusive) and 10.0 (exclusive): println!("Float: {}", rng.random_range(0.0..10.0)); }
Using rand::distr::Uniform
has the same effect but may be faster than rand::Rng::random_range
when repeatedly generating numbers in the same range:
// Import necessary traits and structs from the `rand` crate. use rand::distr::Distribution; use rand::distr::Uniform; fn main() { // Create a random number generator. let mut rng = rand::rng(); // Create a uniform distribution over the range [1, 7). let die = Uniform::try_from(1..7).unwrap(); loop { let throw = die.sample(&mut rng); println!("Roll the die: {throw}"); if throw == 6 { break; } } }
Generate Random Numbers Within a Given Distribution
By default, random numbers in the rand
↗ crate have uniform distribution↗. The rand_distr
↗ crate is a super-set of the rand::distr
module and provides other kinds of statistical distributions. Sample from a distribution using the rand::distr::Distribution::sample
function, passing a random-number generator (implementing rand::Rng
↗).
An example using the rand_distr::Normal
↗ distribution is shown below:
//! This example demonstrates how to sample from a normal distribution. //! //! The `Normal` struct represents a normal distribution with a given mean and //! standard deviation. The `sample` method is used to draw a random sample from //! the distribution. use rand::distr::Distribution; use rand_distr::Normal; use rand_distr::NormalError; /// Sample from a normal distribution with mean 2.0 and standard deviation 3.0. fn main() -> Result<(), NormalError> { let mut rng = rand::rng(); let normal = Normal::new(2.0, 3.0)?; let v = normal.sample(&mut rng); println!("{v} is from a N(2, 3) distribution"); Ok(()) }
Generate Random Values of a Custom Type
The following randomly generates a tuple (i32, bool, f64)
and variable of user defined type Point
, by implementing the [rand::distributions::Distribution
][c~rand::distributions::Distribution~docs]↗ trait:
//! Demonstrates how to implement a custom distribution for the `rand` crate. use rand::Rng; use rand::distr::Distribution; use rand::distr::StandardUniform; /// A simple struct representing a point in 2D space. #[derive(Debug)] #[allow(dead_code)] struct Point { x: i32, y: i32, } // This implementation allows generating random `Point` instances. impl Distribution<Point> for StandardUniform { fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Point { let (x, y) = rng.random::<(i32, i32)>(); Point { x, y } } } fn main() { // Access the standard random value generator: let mut rng = rand::rng(); // Generate a random tuple of (i32, bool, f64): let rand_tuple = rng.random::<(i32, bool, f64)>(); println!("Random tuple: {rand_tuple:?}"); // Generate a random `Point` using the custom implementation. let rand_point: Point = rng.random(); println!("Random Point: {rand_point:?}"); }
Create Random Passwords from a Set of Alphanumeric Characters
In this example, we randomly generate strings of given length from ASCII characters in the range A-Z, a-z, 0-9
, using [rand::distributions::Alphanumeric
][c~rand::distributions::Alphanumeric~docs]↗:
use rand::Rng; use rand::distr::Alphanumeric; use rand::distr::SampleString; /// Generate a random string of 20 alphanumeric characters. fn main() { let rand_string: String = rand::rng() // Create an iterator that generates values using the `Alphanumeric` distribution. .sample_iter(&Alphanumeric) // Take the first 20 characters. .take(20) .map(char::from) .collect(); println!("Randon string: {rand_string}"); // Or use the `SampleString` trait: let rand_string2 = Alphanumeric.sample_string(&mut rand::rng(), 20); println!("Another random string: {rand_string2}"); }
Create Random Passwords from a Set of User-defined Characters
The following randomly generates a string of given length (e.g. a password) using a predefined character set:
use rand::Rng; fn main() { // Define the character set to choose from. const CHARSET: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\ abcdefghijklmnopqrstuvwxyz\ 0123456789)(*&^%$#@!~"; // Define the length of the password. const PASSWORD_LEN: usize = 15; // Get handle to the local `ThreadRng`, which implements `rand::CryptoRng`. // Read the following about the suitability of `rand` to generate random // passwords: <https://docs.rs/rand_distr/latest/rand_distr/struct.Alphanumeric.html#passwords> let mut rng = rand::rng(); let password: String = (0..PASSWORD_LEN) .map(|_| { let idx = rng.random_range(0..CHARSET.len()); CHARSET[idx] as char }) .collect(); println!("{password:?}"); }
Generate Random Numbers with fastrand
fastrand
↗ is a simple and fast random number generator. It has no dependencies and lower complexity than rand
↗ but is NOT cryptographically secure:
//! BEWARE: `fastrand` is NOT cryptographically secure. use std::iter::repeat_with; use fastrand::Rng; fn main() { // To get reproducible results on every run, // pick an arbitrary number as seed. fastrand::seed(42); // Call a function to generate a number, a boolean, a digit, a character... println!("Boolean: {} ", fastrand::bool()); // Or create a new random number generator: let mut rng = Rng::new(); // Generate a random i32: println!("u32: {} ", rng.u32(..100)); // Generate a random `Vec` or `String`: let mut v: Vec<i32> = repeat_with(|| rng.i32(..)).take(5).collect(); println!("Vector: {v:?}"); let s: String = repeat_with(fastrand::alphanumeric).take(10).collect(); println!("String: {s}"); // Sample values from an array or range: println!( "Two samples from the 0..20 interval: {:?}", fastrand::choose_multiple(0..20, 2) ); // Choose a random element in a vector or array: let i = fastrand::usize(..v.len()); let elem = v[i]; println!("Random element: {elem}"); // Shuffle an array: fastrand::shuffle(&mut v); println!("Shuffled vector: {v:?}"); }