std/random.rs
1//! Random value generation.
2//!
3//! The [`Random`] trait allows generating a random value for a type using a
4//! given [`RandomSource`].
5
6#[unstable(feature = "random", issue = "130703")]
7pub use core::random::*;
8
9use crate::sys::random as sys;
10
11/// The default random source.
12///
13/// This asks the system for random data suitable for cryptographic purposes
14/// such as key generation. If security is a concern, consult the platform
15/// documentation below for the specific guarantees your target provides.
16///
17/// The high quality of randomness provided by this source means it can be quite
18/// slow on some targets. If you need a large quantity of random numbers and
19/// security is not a concern, consider using an alternative random number
20/// generator (potentially seeded from this one).
21///
22/// # Underlying sources
23///
24/// Platform | Source
25/// -----------------------|---------------------------------------------------------------
26/// Linux | [`getrandom`] or [`/dev/urandom`] after polling `/dev/random`
27/// Windows | [`ProcessPrng`](https://learn.microsoft.com/en-us/windows/win32/seccng/processprng)
28/// Apple | `CCRandomGenerateBytes`
29/// DragonFly | [`arc4random_buf`](https://man.dragonflybsd.org/?command=arc4random)
30/// ESP-IDF | [`esp_fill_random`](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/random.html#_CPPv415esp_fill_randomPv6size_t)
31/// FreeBSD | [`arc4random_buf`](https://man.freebsd.org/cgi/man.cgi?query=arc4random)
32/// Fuchsia | [`cprng_draw`](https://fuchsia.dev/reference/syscalls/cprng_draw)
33/// Haiku | `arc4random_buf`
34/// Illumos | [`arc4random_buf`](https://www.illumos.org/man/3C/arc4random)
35/// NetBSD | [`arc4random_buf`](https://man.netbsd.org/arc4random.3)
36/// OpenBSD | [`arc4random_buf`](https://man.openbsd.org/arc4random.3)
37/// Solaris | [`arc4random_buf`](https://docs.oracle.com/cd/E88353_01/html/E37843/arc4random-3c.html)
38/// Vita | `arc4random_buf`
39/// Hermit | `read_entropy`
40/// Horizon | `getrandom` shim
41/// AIX, Hurd, L4Re, QNX | `/dev/urandom`
42/// Redox | `/scheme/rand`
43/// RTEMS | [`arc4random_buf`](https://docs.rtems.org/branches/master/bsp-howto/getentropy.html)
44/// SGX | [`rdrand`](https://en.wikipedia.org/wiki/RDRAND)
45/// SOLID | `SOLID_RNG_SampleRandomBytes`
46/// TEEOS | `TEE_GenerateRandom`
47/// UEFI | [`EFI_RNG_PROTOCOL`](https://uefi.org/specs/UEFI/2.10/37_Secure_Technologies.html#random-number-generator-protocol)
48/// VxWorks | `randABytes` after waiting for `randSecure` to become ready
49/// WASI | [`random_get`](https://github.com/WebAssembly/WASI/blob/main/legacy/preview1/docs.md#-random_getbuf-pointeru8-buf_len-size---result-errno)
50/// ZKVM | `sys_rand`
51///
52/// Note that the sources used might change over time.
53///
54/// Consult the documentation for the underlying operations on your supported
55/// targets to determine whether they provide any particular desired properties,
56/// such as support for reseeding on VM fork operations.
57///
58/// [`getrandom`]: https://www.man7.org/linux/man-pages/man2/getrandom.2.html
59/// [`/dev/urandom`]: https://www.man7.org/linux/man-pages/man4/random.4.html
60#[derive(Default, Debug, Clone, Copy)]
61#[unstable(feature = "random", issue = "130703")]
62pub struct DefaultRandomSource;
63
64#[unstable(feature = "random", issue = "130703")]
65impl RandomSource for DefaultRandomSource {
66 fn fill_bytes(&mut self, bytes: &mut [u8]) {
67 sys::fill_bytes(bytes)
68 }
69}
70
71/// Generates a random value with the default random source.
72///
73/// This is a convenience function for `T::random(&mut DefaultRandomSource)` and
74/// will sample according to the same distribution as the underlying [`Random`]
75/// trait implementation. See [`DefaultRandomSource`] for more information about
76/// how randomness is sourced.
77///
78/// **Warning:** Be careful when manipulating random values! The
79/// [`random`](Random::random) method on integers samples them with a uniform
80/// distribution, so a value of 1 is just as likely as [`i32::MAX`]. By using
81/// modulo operations, some of the resulting values can become more likely than
82/// others. Use audited crates when in doubt.
83///
84/// # Examples
85///
86/// Generating a [version 4/variant 1 UUID] represented as text:
87/// ```
88/// #![feature(random)]
89///
90/// use std::random::random;
91///
92/// let bits: u128 = random();
93/// let g1 = (bits >> 96) as u32;
94/// let g2 = (bits >> 80) as u16;
95/// let g3 = (0x4000 | (bits >> 64) & 0x0fff) as u16;
96/// let g4 = (0x8000 | (bits >> 48) & 0x3fff) as u16;
97/// let g5 = (bits & 0xffffffffffff) as u64;
98/// let uuid = format!("{g1:08x}-{g2:04x}-{g3:04x}-{g4:04x}-{g5:012x}");
99/// println!("{uuid}");
100/// ```
101///
102/// [version 4/variant 1 UUID]: https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)
103#[unstable(feature = "random", issue = "130703")]
104pub fn random<T: Random>() -> T {
105 T::random(&mut DefaultRandomSource)
106}