std: implement the random
feature · qinheping/verify-rust-std@a095a76 (original) (raw)
``
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 = "none")]
`
``
7
`+
pub use core::random::*;
`
``
8
+
``
9
`+
use 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. If you need a large quantity of random numbers and security is not a
`
``
19
`+
/// concern, consider using an alternative random number generator (potentially
`
``
20
`+
/// 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
]
``
``
28
`` +
/// macOS and other UNIXes | [getentropy
]
``
``
29
`` +
/// other Apple platforms | CCRandomGenerateBytes
``
``
30
`` +
/// ESP-IDF | [esp_fill_random
]
``
``
31
`` +
/// Fuchsia | [cprng_draw
]
``
``
32
`` +
/// Hermit | read_entropy
``
``
33
`` +
/// Horizon | getrandom
shim
``
``
34
`` +
/// Hurd, L4Re, QNX | /dev/urandom
``
``
35
`` +
/// NetBSD before 10.0 | [kern.arandom
]
``
``
36
`` +
/// Redox | /scheme/rand
``
``
37
`` +
/// SGX | [rdrand
]
``
``
38
`` +
/// SOLID | SOLID_RNG_SampleRandomBytes
``
``
39
`` +
/// TEEOS | TEE_GenerateRandom
``
``
40
`` +
/// UEFI | [EFI_RNG_PROTOCOL
]
``
``
41
`` +
/// VxWorks | randABytes
after waiting for randSecure
to become ready
``
``
42
`` +
/// WASI | random_get
``
``
43
`` +
/// ZKVM | sys_rand
``
``
44
`+
///
`
``
45
`+
/// Disclaimer: The sources used might change over time.
`
``
46
`+
///
`
``
47
`` +
/// [getrandom
]: https://www.man7.org/linux/man-pages/man2/getrandom.2.html
``
``
48
`` +
/// [/dev/urandom
]: https://www.man7.org/linux/man-pages/man4/random.4.html
``
``
49
`` +
/// [ProcessPrng
]: https://learn.microsoft.com/en-us/windows/win32/seccng/processprng
``
``
50
`` +
/// [getentropy
]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getentropy.html
``
``
51
`` +
/// [esp_fill_random
]: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/random.html#_CPPv415esp_fill_randomPv6size_t
``
``
52
`` +
/// [cprng_draw
]: https://fuchsia.dev/reference/syscalls/cprng_draw
``
``
53
`` +
/// [kern.arandom
]: https://man.netbsd.org/rnd.4
``
``
54
`` +
/// [rdrand
]: https://en.wikipedia.org/wiki/RDRAND
``
``
55
`` +
/// [EFI_RNG_PROTOCOL
]: https://uefi.org/specs/UEFI/2.10/37_Secure_Technologies.html#random-number-generator-protocol
``
``
56
`+
#[derive(Default, Debug, Clone, Copy)]
`
``
57
`+
#[unstable(feature = "random", issue = "none")]
`
``
58
`+
pub struct DefaultRandomSource;
`
``
59
+
``
60
`+
#[unstable(feature = "random", issue = "none")]
`
``
61
`+
impl RandomSource for DefaultRandomSource {
`
``
62
`+
fn fill_bytes(&mut self, bytes: &mut [u8]) {
`
``
63
`+
sys::fill_bytes(bytes)
`
``
64
`+
}
`
``
65
`+
}
`
``
66
+
``
67
`+
/// Generates a random value with the default random source.
`
``
68
`+
///
`
``
69
`` +
/// This is a convenience function for T::random(&mut DefaultRandomSource)
and
``
``
70
`` +
/// will sample according to the same distribution as the underlying [Random
]
``
``
71
`+
/// trait implementation.
`
``
72
`+
///
`
``
73
`+
/// Warning: Be careful when manipulating random values! The
`
``
74
`` +
/// random
method on integers samples them with a uniform
``
``
75
`` +
/// distribution, so a value of 1 is just as likely as [i32::MAX
]. By using
``
``
76
`+
/// modulo operations, some of the resulting values can become more likely than
`
``
77
`+
/// others. Use audited crates when in doubt.
`
``
78
`+
///
`
``
79
`+
/// # Examples
`
``
80
`+
///
`
``
81
`+
/// Generating a [version 4/variant 1 UUID] represented as text:
`
``
82
/// ```
``
83
`+
/// #![feature(random)]
`
``
84
`+
///
`
``
85
`+
/// use std::random::random;
`
``
86
`+
///
`
``
87
`+
/// let bits = random::();
`
``
88
`+
/// let g1 = (bits >> 96) as u32;
`
``
89
`+
/// let g2 = (bits >> 80) as u16;
`
``
90
`+
/// let g3 = (0x4000 | (bits >> 64) & 0x0fff) as u16;
`
``
91
`+
/// let g4 = (0x8000 | (bits >> 48) & 0x3fff) as u16;
`
``
92
`+
/// let g5 = (bits & 0xffffffffffff) as u64;
`
``
93
`+
/// let uuid = format!("{g1:08x}-{g2:04x}-{g3:04x}-{g4:04x}-{g5:012x}");
`
``
94
`+
/// println!("{uuid}");
`
``
95
/// ```
``
96
`+
///
`
``
97
`+
/// [version 4/variant 1 UUID]: https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)
`
``
98
`+
pub fn random<T: Random>() -> T {
`
``
99
`+
T::random(&mut DefaultRandomSource)
`
``
100
`+
}
`