|
9 | 9 | // except according to those terms.
|
10 | 10 |
|
11 | 11 | //! Utilities for random number generation
|
12 |
| -//! |
13 |
| -//! ## Example |
14 |
| -//! |
15 |
| -//! ```rust |
| 12 | +//! |
| 13 | +//! Rand provides utilities to generate random numbers, to convert them to |
| 14 | +//! useful types and distributions, and some randomness-related algorithms. |
| 15 | +//! |
| 16 | +//! # Basic use |
| 17 | +//! |
| 18 | +//! To quickly get you started, the easiest and most high-level way to just get |
| 19 | +//! some random value is to use [`random()`]. |
| 20 | +//! |
| 21 | +//! ``` |
| 22 | +//! let x: u8 = rand::random(); |
| 23 | +//! println!("{}", x); |
| 24 | +//! |
| 25 | +//! let y = rand::random::<f64>(); |
| 26 | +//! println!("{}", y); |
| 27 | +//! |
| 28 | +//! if rand::random() { // generates a boolean |
| 29 | +//! println!("Heads!"); |
| 30 | +//! } |
| 31 | +//! ``` |
| 32 | +//! |
| 33 | +//! This functionality is however very basic. As soon as you need something |
| 34 | +//! slightly more specific, like a random value in some range, you have to know |
| 35 | +//! a bit more about how things work. |
| 36 | +//! |
| 37 | +//! |
| 38 | +//! # The two-step process to get a random value |
| 39 | +//! |
| 40 | +//! To get a random value, you usually need two pieces: |
| 41 | +//! |
| 42 | +//! - a random number generator (RNG); |
| 43 | +//! - some function to transform the 'bag of bits' from the RNG to a value you |
| 44 | +//! can use (which we call a distribution, although we use the term for a bit |
| 45 | +//! more functionality than what fits the meaning). |
| 46 | +//! |
| 47 | +//! There are many kinds of RNGs, with different trade-offs. Rand comes with a |
| 48 | +//! good all-use default, [`ThreadRng`]. Is is easily available through the |
| 49 | +//! [`thread_rng()`] function. It is reasonably fast and has good quality (secure |
| 50 | +//! and without patterns). |
| 51 | +//! |
| 52 | +//! To turn the output of the RNG into something usable, you usually want to use |
| 53 | +//! the methods from the [`Rng`] trait: |
| 54 | +//! |
| 55 | +//! - [`gen`] generates a random value appropriate for the type. |
| 56 | +//! For example `let val: u16 = rng.gen()` will produces a random value |
| 57 | +//! between 0 and `std::u16::MAX`. But for floats the value will be generated |
| 58 | +//! uniformly between 0 and 1, which is more useful than a completely random |
| 59 | +//! float value (including NaN and infinity); |
| 60 | +//! - [`gen_range`] samples from a specific range of values; |
| 61 | +//! - [`sample`] samples directly from some distribution, useful for all |
| 62 | +//! situations where you need something slightly more complex. |
| 63 | +//! |
| 64 | +//! [`random()`] is nothing more than `thread_rng().gen()`. |
| 65 | +//! |
| 66 | +//! ## Further reading |
| 67 | +//! |
| 68 | +//! The [`rngs` module] provides more background on RNGs. For example: What are |
| 69 | +//! [`StdRng`] and [`SmallRng`], and why use them? Why do some RNGs need |
| 70 | +//! seeding, and where do you get a seed? |
| 71 | +//! |
| 72 | +//! The [`distributions` module] provides more documentation on distributions. |
| 73 | +//! How do you make [`Rng::gen`] available for a custom type? What are |
| 74 | +//! distributions good for? How do you sample from probability distributions? |
| 75 | +//! |
| 76 | +//! |
| 77 | +//! ## Examples |
| 78 | +//! |
| 79 | +//! ``` |
16 | 80 | //! // Rng is the main trait and needs to be imported:
|
17 | 81 | //! use rand::{Rng, thread_rng};
|
18 | 82 | //!
|
|
21 | 85 | //! if rng.gen() { // random bool
|
22 | 86 | //! let x: f64 = rng.gen(); // random number in range (0, 1)
|
23 | 87 | //! println!("x is: {}", x);
|
| 88 | +//! let char = rng.gen::<char>(); // Sometimes you need type annotation |
| 89 | +//! println!("char is: {}", char); |
24 | 90 | //! println!("Number from 0 to 9: {}", rng.gen_range(0, 10));
|
25 | 91 | //! }
|
26 | 92 | //! ```
|
27 | 93 | //!
|
28 |
| -//! The key function is [`Rng::gen()`]. It is polymorphic and so can be used to |
29 |
| -//! generate many types; the [`Standard`] distribution carries the |
30 |
| -//! implementations. In some cases type annotation is required, e.g. |
31 |
| -//! `rng.gen::<f64>()`. |
32 | 94 | //!
|
33 |
| -//! # Getting random values |
| 95 | +//! # Other functionality |
34 | 96 | //!
|
35 |
| -//! The most convenient source of randomness is likely [`thread_rng`], which |
36 |
| -//! automatically initialises a fast algorithmic generator on first use per |
37 |
| -//! thread with thread-local storage. |
38 |
| -//! |
39 |
| -//! If one wants to obtain random data directly from an external source it is |
40 |
| -//! recommended to use [`EntropyRng`] which manages multiple available sources |
41 |
| -//! or [`OsRng`] which retrieves random data directly from the OS. It should be |
42 |
| -//! noted that this is significantly slower than using a local generator like |
43 |
| -//! [`thread_rng`] and potentially much slower if [`EntropyRng`] must fall back to |
44 |
| -//! [`JitterRng`] as a source. |
45 |
| -//! |
46 |
| -//! It is also common to use an algorithmic generator in local memory; this may |
47 |
| -//! be faster than `thread_rng` and provides more control. In this case |
48 |
| -//! [`StdRng`] — the generator behind [`thread_rng`] — and [`SmallRng`] — a |
49 |
| -//! small, fast, weak generator — are good choices; more options can be found in |
50 |
| -//! the [`prng`] module as well as in other crates. |
51 |
| -//! |
52 |
| -//! Local generators need to be seeded. It is recommended to use [`FromEntropy`] or |
53 |
| -//! to seed from a strong parent generator with [`from_rng`]: |
54 |
| -//! |
55 |
| -//! ``` |
56 |
| -//! # use rand::{Rng, Error}; |
57 |
| -//! // seed with fresh entropy: |
58 |
| -//! use rand::{StdRng, FromEntropy}; |
59 |
| -//! let mut rng = StdRng::from_entropy(); |
60 |
| -//! # let v: u32 = rng.gen(); |
61 |
| -//! |
62 |
| -//! // seed from thread_rng: |
63 |
| -//! use rand::{SmallRng, SeedableRng, thread_rng}; |
| 97 | +//! The ability to generate random values is not the only thing Rand provides. |
| 98 | +//! Most functionality is available through the [`Rng`] trait, so that is useful |
| 99 | +//! to explore. Some of its methods include: |
64 | 100 | //!
|
65 |
| -//! # fn try_inner() -> Result<(), Error> { |
66 |
| -//! let mut rng = SmallRng::from_rng(thread_rng())?; |
67 |
| -//! # let v: u32 = rng.gen(); |
68 |
| -//! # Ok(()) |
69 |
| -//! # } |
70 |
| -//! # try_inner().unwrap() |
71 |
| -//! ``` |
72 |
| -//! |
73 |
| -//! In case you specifically want to have a reproducible stream of "random" |
74 |
| -//! data (e.g. to procedurally generate a game world), select a named algorithm |
75 |
| -//! (i.e. not [`StdRng`]/[`SmallRng`] which may be adjusted in the future), and |
76 |
| -//! use [`SeedableRng::from_seed`] or a constructor specific to the generator |
77 |
| -//! (e.g. [`IsaacRng::new_from_u64`]). |
78 |
| -//! |
79 |
| -//! ## Applying / converting random data |
80 |
| -//! |
81 |
| -//! The [`RngCore`] trait allows generators to implement a common interface for |
82 |
| -//! retrieving random data, but how should you use this? Typically users should |
83 |
| -//! use the [`Rng`] trait not [`RngCore`]; this provides more flexible ways to |
84 |
| -//! access the same data (e.g. `gen()` can output many more types than |
85 |
| -//! `next_u32()` and `next_u64()`; Rust's optimiser should eliminate any |
86 |
| -//! overhead). It also provides several useful algorithms, |
87 |
| -//! e.g. `gen_bool(p)` to generate events with weighted probability and |
88 |
| -//! `shuffle(&mut v[..])` to randomly-order a vector. |
89 |
| -//! |
90 |
| -//! The [`distributions`] module provides several more ways to convert random |
91 |
| -//! data to useful values, e.g. time of decay is often modelled with an |
92 |
| -//! exponential distribution, and the log-normal distribution provides a good |
93 |
| -//! model of many natural phenomona. |
94 |
| -//! |
95 |
| -//! The [`seq`] module has a few tools applicable to sliceable or iterable data. |
96 |
| -//! |
97 |
| -//! ## Cryptographic security |
98 |
| -//! |
99 |
| -//! First, lets recap some terminology: |
| 101 | +//! - [`Rng::sample_iter`] to get an iterator for the choosen distribution. |
| 102 | +//! - [`Rng::gen_bool`] to generate events with weighted probability. |
| 103 | +//! - [`Rng::fill`] and [`Rng::try_fill`] as fast alternatives to fill a slice |
| 104 | +//! of integers. |
| 105 | +//! - [`Rng::shuffle`] can be used to shuffle slices. |
| 106 | +//! - [`Rng::choose`] to pick one element at random from a slice, and the |
| 107 | +//! functions in the [`seq`] module to the pick multiple. |
| 108 | +//! |
| 109 | +//! Also there is [`distributions::WeightedChoice`], which can be used to pick |
| 110 | +//! elements at random with some probability. But it does not work well at the |
| 111 | +//! moment and is going through a redesign. |
| 112 | +//! |
| 113 | +//! |
| 114 | +//! # Error handling |
| 115 | +//! |
| 116 | +//! The story around error handling in Rand is a bit of a practical compromise. |
| 117 | +//! On one hand PRNGs and distributions are never supposed to produce an error. |
| 118 | +//! Threading error handling through them would be unnecessary and make Rand |
| 119 | +//! very unergonomic to use. On the other hand external RNGs, like those from |
| 120 | +//! the OS or a hardware device, very well may produce an error. |
| 121 | +//! |
| 122 | +//! All methods that normally would only be used in combination with a PRNG |
| 123 | +//! always just produce a value. This might mean a fallible RNG has to panic |
| 124 | +//! if it is unable to return a value when used in combination with these |
| 125 | +//! methods. |
| 126 | +//! |
| 127 | +//! Only the handful of methods that are usually desired for external RNGs can |
| 128 | +//! report errors, such as [`Rng::try_fill`], [`RngCore::try_fill_bytes`], and |
| 129 | +//! [`SeedableRng::from_rng`]. |
| 130 | +//! |
| 131 | +//! |
| 132 | +//! # Distinction between Rand and `rand_core` |
| 133 | +//! |
| 134 | +//! [`rand_core`] provides all the parts necessary for implementing RNGs, among |
| 135 | +//! which are the [`RngCore`] and [`SeedableRng`] traits, and an [`Error`] type. |
| 136 | +//! Crates implementing RNGs would ideally depend on [`rand_core`]. |
| 137 | +//! |
| 138 | +//! Common applicaties and libraries however are encouraged to use the Rand |
| 139 | +//! crate instead, which re-exports the main traits and error types. |
100 | 140 | //!
|
101 |
| -//! - **PRNG:** *Pseudo-Random-Number-Generator* is another name for an |
102 |
| -//! *algorithmic generator* |
103 |
| -//! - **CSPRNG:** a *Cryptographically Secure* PRNG |
104 | 141 | //!
|
105 |
| -//! Security analysis requires a threat model and expert review; we can provide |
106 |
| -//! neither, but we can provide a few hints. We assume that the goal is to |
107 |
| -//! produce secret apparently-random data. Therefore, we need: |
108 |
| -//! |
109 |
| -//! - A good source of entropy. A known algorithm given known input data is |
110 |
| -//! trivial to predict, and likewise if there's a non-negligable chance that |
111 |
| -//! the input to a PRNG is guessable then there's a chance its output is too. |
112 |
| -//! We recommend seeding CSPRNGs with [`EntropyRng`] or [`OsRng`] which |
113 |
| -//! provide fresh "random" values from an external source. |
114 |
| -//! One can also seed from another CSPRNG, e.g. `thread_rng`, which is faster, |
115 |
| -//! but adds another component which must be trusted. |
116 |
| -//! - A strong algorithmic generator. It is possible to use a good entropy |
117 |
| -//! source like `OsRng` directly, and in some cases this is the best option, |
118 |
| -//! but for better performance (or if requiring reproducible values generated |
119 |
| -//! from a fixed seed) it is common to use a local CSPRNG. The basic security |
120 |
| -//! that CSPRNGs must provide is making it infeasible to predict future output |
121 |
| -//! given a sample of past output. A further security that *some* CSPRNGs |
122 |
| -//! provide is *forward secrecy*; this ensures that in the event that the |
123 |
| -//! algorithm's state is revealed, it is infeasible to reconstruct past |
124 |
| -//! output. See the [`CryptoRng`] trait and notes on individual algorithms. |
125 |
| -//! - To be careful not to leak secrets like keys and CSPRNG's internal state |
126 |
| -//! and robust against "side channel attacks". This goes well beyond the scope |
127 |
| -//! of random number generation, but this crate takes some precautions: |
128 |
| -//! - to avoid printing CSPRNG state in log files, implementations have a |
129 |
| -//! custom `Debug` implementation which omits all internal state |
130 |
| -//! - `thread_rng` uses [`ReseedingRng`] to periodically refresh its state |
131 |
| -//! - in the future we plan to add some protection against fork attacks |
132 |
| -//! (where the process is forked and each clone generates the same "random" |
133 |
| -//! numbers); this is not yet implemented (see issues #314, #370) |
134 |
| -//! |
135 | 142 | //! # Examples
|
136 | 143 | //!
|
137 | 144 | //! For some inspiration, see the examples:
|
138 |
| -//! |
139 |
| -//! * [Monte Carlo estimation of π]( |
140 |
| -//! https://github.com/rust-lang-nursery/rand/blob/master/examples/monte-carlo.rs) |
141 |
| -//! * [Monty Hall Problem]( |
142 |
| -//! https://github.com/rust-lang-nursery/rand/blob/master/examples/monty-hall.rs) |
143 | 145 | //!
|
144 |
| -//! [`Rng`]: trait.Rng.html |
145 |
| -//! [`Rng::gen()`]: trait.Rng.html#method.gen |
| 146 | +//! - [Monte Carlo estimation of π]( |
| 147 | +//! https://github.com/rust-lang-nursery/rand/blob/master/examples/monte-carlo.rs) |
| 148 | +//! - [Monty Hall Problem]( |
| 149 | +//! https://github.com/rust-lang-nursery/rand/blob/master/examples/monty-hall.rs) |
| 150 | +//! |
| 151 | +//! |
| 152 | +//! [`distributions` module]: distributions/index.html |
| 153 | +//! [`distributions::WeightedChoice`]: distributions/struct.WeightedChoice.html |
| 154 | +//! [`Error`]: struct.Error.html |
| 155 | +//! [`gen_range`]: trait.Rng.html#method.gen_range |
| 156 | +//! [`gen`]: trait.Rng.html#method.gen |
| 157 | +//! [`rand_core`]: https://crates.io/crates/rand_core |
| 158 | +//! [`random()`]: fn.random.html |
| 159 | +//! [`Rng::choose`]: trait.Rng.html#method.choose |
| 160 | +//! [`Rng::fill`]: trait.Rng.html#method.fill |
| 161 | +//! [`Rng::gen_bool`]: trait.Rng.html#method.gen_bool |
| 162 | +//! [`Rng::gen`]: trait.Rng.html#method.gen |
| 163 | +//! [`Rng::sample_iter`]: trait.Rng.html#method.sample_iter |
| 164 | +//! [`Rng::shuffle`]: trait.Rng.html#method.shuffle |
146 | 165 | //! [`RngCore`]: trait.RngCore.html
|
147 |
| -//! [`FromEntropy`]: trait.FromEntropy.html |
148 |
| -//! [`SeedableRng::from_seed`]: trait.SeedableRng.html#tymethod.from_seed |
149 |
| -//! [`from_rng`]: trait.SeedableRng.html#method.from_rng |
150 |
| -//! [`CryptoRng`]: trait.CryptoRng.html |
151 |
| -//! [`thread_rng`]: fn.thread_rng.html |
152 |
| -//! [`EntropyRng`]: struct.EntropyRng.html |
153 |
| -//! [`OsRng`]: os/struct.OsRng.html |
154 |
| -//! [`JitterRng`]: jitter/struct.JitterRng.html |
155 |
| -//! [`StdRng`]: struct.StdRng.html |
156 |
| -//! [`SmallRng`]: struct.SmallRng.html |
157 |
| -//! [`ReseedingRng`]: reseeding/struct.ReseedingRng.html |
158 |
| -//! [`prng`]: prng/index.html |
159 |
| -//! [`IsaacRng::new_from_u64`]: prng/isaac/struct.IsaacRng.html#method.new_from_u64 |
160 |
| -//! [`Hc128Rng`]: prng/hc128/struct.Hc128Rng.html |
161 |
| -//! [`ChaChaRng`]: prng/chacha/struct.ChaChaRng.html |
162 |
| -//! [`IsaacRng`]: prng/isaac/struct.IsaacRng.html |
163 |
| -//! [`Isaac64Rng`]: prng/isaac64/struct.Isaac64Rng.html |
| 166 | +//! [`RngCore::try_fill_bytes`]: trait.RngCore.html#method.try_fill_bytes |
| 167 | +//! [`rngs` module]: rngs/index.html |
| 168 | +//! [`Rng`]: trait.Rng.html |
| 169 | +//! [`Rng::try_fill`]: trait.Rng.html#method.try_fill |
| 170 | +//! [`sample`]: trait.Rng.html#method.sample |
| 171 | +//! [`SeedableRng`]: trait.SeedableRng.html |
| 172 | +//! [`SeedableRng::from_rng`]: trait.SeedableRng.html#method.from_rng |
164 | 173 | //! [`seq`]: seq/index.html
|
165 |
| -//! [`distributions`]: distributions/index.html |
166 |
| -//! [`Standard`]: distributions/struct.Standard.html |
| 174 | +//! [`SmallRng`]: struct.SmallRng.html |
| 175 | +//! [`StdRng`]: struct.StdRng.html |
| 176 | +//! [`thread_rng()`]: fn.thread_rng.html |
| 177 | +//! [`ThreadRng`]: rngs/struct.ThreadRng.html |
| 178 | +
|
167 | 179 |
|
168 | 180 | #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
|
169 | 181 | html_favicon_url = "https://www.rust-lang.org/favicon.ico",
|
|
0 commit comments