diff --git a/rand_core/src/impls.rs b/rand_core/src/impls.rs index 5e516d92382..439b46b8098 100644 --- a/rand_core/src/impls.rs +++ b/rand_core/src/impls.rs @@ -119,7 +119,7 @@ macro_rules! fill_via_chunks { /// # Example /// (from `IsaacRng`) /// -/// ```rust,ignore +/// ```ignore /// fn fill_bytes(&mut self, dest: &mut [u8]) { /// let mut read_len = 0; /// while read_len < dest.len() { diff --git a/rand_core/src/lib.rs b/rand_core/src/lib.rs index 1fa79bf7b10..5624d613980 100644 --- a/rand_core/src/lib.rs +++ b/rand_core/src/lib.rs @@ -109,7 +109,7 @@ pub mod le; /// /// A simple example, obviously not generating very *random* output: /// -/// ```rust +/// ``` /// #![allow(dead_code)] /// use rand_core::{RngCore, Error, impls}; /// diff --git a/src/distributions/binomial.rs b/src/distributions/binomial.rs index eb716f444b7..7e4e869c153 100644 --- a/src/distributions/binomial.rs +++ b/src/distributions/binomial.rs @@ -22,7 +22,7 @@ use std::f64::consts::PI; /// /// # Example /// -/// ```rust +/// ``` /// use rand::distributions::{Binomial, Distribution}; /// /// let bin = Binomial::new(20, 0.3); diff --git a/src/distributions/exponential.rs b/src/distributions/exponential.rs index 8c55f804c5b..de6564eabcd 100644 --- a/src/distributions/exponential.rs +++ b/src/distributions/exponential.rs @@ -29,7 +29,7 @@ use distributions::{ziggurat, ziggurat_tables, Distribution}; /// College, Oxford /// /// # Example -/// ```rust +/// ``` /// use rand::prelude::*; /// use rand::distributions::Exp1; /// @@ -66,7 +66,7 @@ impl Distribution for Exp1 { /// /// # Example /// -/// ```rust +/// ``` /// use rand::distributions::{Exp, Distribution}; /// /// let exp = Exp::new(2.0); diff --git a/src/distributions/float.rs b/src/distributions/float.rs index 83af82984b4..0058122443c 100644 --- a/src/distributions/float.rs +++ b/src/distributions/float.rs @@ -27,7 +27,7 @@ use distributions::{Distribution, Standard}; /// ranges. /// /// # Example -/// ```rust +/// ``` /// use rand::{thread_rng, Rng}; /// use rand::distributions::OpenClosed01; /// @@ -53,7 +53,7 @@ pub struct OpenClosed01; /// ranges. /// /// # Example -/// ```rust +/// ``` /// use rand::{thread_rng, Rng}; /// use rand::distributions::Open01; /// diff --git a/src/distributions/gamma.rs b/src/distributions/gamma.rs index ba4f53bfba2..44e1c5929fa 100644 --- a/src/distributions/gamma.rs +++ b/src/distributions/gamma.rs @@ -35,7 +35,7 @@ use distributions::{Distribution, Exp, Open01}; /// /// # Example /// -/// ```rust +/// ``` /// use rand::distributions::{Distribution, Gamma}; /// /// let gamma = Gamma::new(2.0, 5.0); @@ -178,7 +178,7 @@ impl Distribution for GammaLargeShape { /// /// # Example /// -/// ```rust +/// ``` /// use rand::distributions::{ChiSquared, Distribution}; /// /// let chi = ChiSquared::new(11.0); @@ -233,7 +233,7 @@ impl Distribution for ChiSquared { /// /// # Example /// -/// ```rust +/// ``` /// use rand::distributions::{FisherF, Distribution}; /// /// let f = FisherF::new(2.0, 32.0); @@ -274,7 +274,7 @@ impl Distribution for FisherF { /// /// # Example /// -/// ```rust +/// ``` /// use rand::distributions::{StudentT, Distribution}; /// /// let t = StudentT::new(11.0); diff --git a/src/distributions/mod.rs b/src/distributions/mod.rs index a7761e388bf..65195160013 100644 --- a/src/distributions/mod.rs +++ b/src/distributions/mod.rs @@ -83,6 +83,7 @@ //! - [`Normal`] distribution, and [`StandardNormal`] as a primitive //! - Related to Bernoulli trials (yes/no events, with a given probability): //! - [`Binomial`] distribution +//! - [`Bernoulli`] distribution, similar to [`Rng::gen_bool`]. //! - Related to positive real-valued quantities that grow exponentially //! (e.g. prices, incomes, populations): //! - [`LogNormal`] distribution @@ -145,6 +146,7 @@ //! [Floating point implementation]: struct.Standard.html#floating-point-implementation // distributions //! [`Alphanumeric`]: struct.Alphanumeric.html +//! [`Bernoulli`]: struct.Bernoulli.html //! [`Binomial`]: struct.Binomial.html //! [`ChiSquared`]: struct.ChiSquared.html //! [`Exp`]: struct.Exp.html diff --git a/src/distributions/normal.rs b/src/distributions/normal.rs index ac24b018c58..69ee6a0d9c2 100644 --- a/src/distributions/normal.rs +++ b/src/distributions/normal.rs @@ -27,7 +27,7 @@ use distributions::{ziggurat, ziggurat_tables, Distribution, Open01}; /// College, Oxford /// /// # Example -/// ```rust +/// ``` /// use rand::prelude::*; /// use rand::distributions::StandardNormal; /// @@ -79,7 +79,7 @@ impl Distribution for StandardNormal { /// /// # Example /// -/// ```rust +/// ``` /// use rand::distributions::{Normal, Distribution}; /// /// // mean 2, standard deviation 3 @@ -124,7 +124,7 @@ impl Distribution for Normal { /// /// # Example /// -/// ```rust +/// ``` /// use rand::distributions::{LogNormal, Distribution}; /// /// // mean 2, standard deviation 3 diff --git a/src/distributions/other.rs b/src/distributions/other.rs index 317877c3650..ef8ce63b8b0 100644 --- a/src/distributions/other.rs +++ b/src/distributions/other.rs @@ -23,7 +23,7 @@ use distributions::{Distribution, Standard, Uniform}; /// /// # Example /// -/// ```rust +/// ``` /// use std::iter; /// use rand::{Rng, thread_rng}; /// use rand::distributions::Alphanumeric; diff --git a/src/distributions/poisson.rs b/src/distributions/poisson.rs index d1fa901542e..8fbf031d0c7 100644 --- a/src/distributions/poisson.rs +++ b/src/distributions/poisson.rs @@ -22,7 +22,7 @@ use std::f64::consts::PI; /// /// # Example /// -/// ```rust +/// ``` /// use rand::distributions::{Poisson, Distribution}; /// /// let poi = Poisson::new(2.0); diff --git a/src/lib.rs b/src/lib.rs index 79fe0f31823..a47a107f3b1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,163 +9,217 @@ // except according to those terms. //! Utilities for random number generation +//! +//! Rand provides utilities to generate random numbers, to convert them to +//! useful types and distributions, and some randomness-related algorithms. +//! +//! # Basic usage +//! +//! To get you started quickly, the easiest and highest-level way to get +//! a random value is to use [`random()`]. +//! +//! ``` +//! let x: u8 = rand::random(); +//! println!("{}", x); +//! +//! let y = rand::random::(); +//! println!("{}", y); +//! +//! if rand::random() { // generates a boolean +//! println!("Heads!"); +//! } +//! ``` +//! +//! This supports generating most common types but is not very flexible, thus +//! you probably want to learn a bit more about the Rand library. +//! +//! +//! # The two-step process to get a random value +//! +//! Generating random values is typically a two-step process: +//! +//! - get some *random data* (an integer or bit/byte sequence) from a random +//! number generator (RNG); +//! - use some function to transform that *data* into the type of value you want +//! (this function is an implementation of some *distribution* describing the +//! kind of value produced). +//! +//! Rand represents the first step with the [`RngCore`] trait and the second +//! step via a combination of the [`Rng`] extension trait and the +//! [`distributions` module]. +//! In practice you probably won't use [`RngCore`] directly unless you are +//! implementing a random number generator (RNG). +//! +//! There are many kinds of RNGs, with different trade-offs. You can read more +//! about them in the [`rngs` module] and even more in the [`prng` module], +//! however, often you can just use [`thread_rng()`]. This function +//! automatically initializes an RNG in thread-local memory, then returns a +//! reference to it. It is fast, good quality, and secure (unpredictable). +//! +//! To turn the output of the RNG into something usable, you usually want to use +//! the methods from the [`Rng`] trait. Some of the most useful methods are: +//! +//! - [`gen`] generates a random value appropriate for the type (just like +//! [`random()`]). For integers this is normally the full representable range +//! (e.g. from `0u32` to `std::u32::MAX`), for floats this is between 0 and 1, +//! and some other types are supported, including arrays and tuples. See the +//! [`Standard`] distribution which provides the implementations. +//! - [`gen_range`] samples from a specific range of values; this is like +//! [`gen`] but with specific upper and lower bounds. +//! - [`sample`] samples directly from some distribution. +//! +//! [`random()`] is defined using just the above: `thread_rng().gen()`. +//! +//! ## Distributions +//! +//! What are distributions, you ask? Specifying only the type and range of +//! values (known as the *sample space*) is not enough; samples must also have +//! a *probability distribution*, describing the relative probability of +//! sampling each value in that space. +//! +//! In many cases a *uniform* distribution is used, meaning roughly that each +//! value is equally likely (or for "continuous" types like floats, that each +//! equal-sized sub-range has the same probability of containing a sample). +//! [`gen`] and [`gen_range`] both use statistically uniform distributions. +//! +//! The [`distributions` module] provides implementations +//! of some other distributions, including Normal, Log-Normal and Exponential. //! -//! ## Example -//! -//! ```rust -//! // Rng is the main trait and needs to be imported: -//! use rand::{Rng, thread_rng}; +//! It is worth noting that the functionality already mentioned is implemented +//! with distributions: [`gen`] samples values using the [`Standard`] +//! distribution, while [`gen_range`] uses [`Uniform`]. +//! +//! ## Importing (prelude) +//! +//! The most convenient way to import items from Rand is to use the [prelude]. +//! This includes the most important parts of Rand, but only those unlikely to +//! cause name conflicts. +//! +//! Note that Rand 0.5 has significantly changed the module organization and +//! contents relative to previous versions. Where possible old names have been +//! kept (but are hidden in the documentation), however these will be removed +//! in the future. We therefore recommend migrating to use the prelude or the +//! new module organization in your imports. +//! +//! +//! ## Examples +//! +//! ``` +//! use rand::prelude::*; //! //! // thread_rng is often the most convenient source of randomness: //! let mut rng = thread_rng(); +//! //! if rng.gen() { // random bool //! let x: f64 = rng.gen(); // random number in range (0, 1) //! println!("x is: {}", x); +//! let char = rng.gen::(); // using type annotation +//! println!("char is: {}", char); //! println!("Number from 0 to 9: {}", rng.gen_range(0, 10)); //! } //! ``` //! -//! The key function is [`Rng::gen()`]. It is polymorphic and so can be used to -//! generate many types; the [`Standard`] distribution carries the -//! implementations. In some cases type annotation is required, e.g. -//! `rng.gen::()`. //! -//! # Getting random values +//! # More functionality //! -//! The most convenient source of randomness is likely [`thread_rng`], which -//! automatically initialises a fast algorithmic generator on first use per -//! thread with thread-local storage. -//! -//! If one wants to obtain random data directly from an external source it is -//! recommended to use [`EntropyRng`] which manages multiple available sources -//! or [`OsRng`] which retrieves random data directly from the OS. It should be -//! noted that this is significantly slower than using a local generator like -//! [`thread_rng`] and potentially much slower if [`EntropyRng`] must fall back to -//! [`JitterRng`] as a source. -//! -//! It is also common to use an algorithmic generator in local memory; this may -//! be faster than `thread_rng` and provides more control. In this case -//! [`StdRng`] — the generator behind [`thread_rng`] — and [`SmallRng`] — a -//! small, fast, weak generator — are good choices; more options can be found in -//! the [`prng`] module as well as in other crates. -//! -//! Local generators need to be seeded. It is recommended to use [`FromEntropy`] or -//! to seed from a strong parent generator with [`from_rng`]: -//! -//! ``` -//! # use rand::{Rng, Error}; -//! // seed with fresh entropy: -//! use rand::FromEntropy; -//! use rand::rngs::StdRng; -//! let mut rng = StdRng::from_entropy(); -//! # let v: u32 = rng.gen(); -//! -//! // seed from thread_rng: -//! use rand::{SeedableRng, thread_rng}; -//! use rand::rngs::SmallRng; +//! The [`Rng`] trait includes a few more methods not mentioned above: //! -//! # fn try_inner() -> Result<(), Error> { -//! let mut rng = SmallRng::from_rng(thread_rng())?; -//! # let v: u32 = rng.gen(); -//! # Ok(()) -//! # } -//! # try_inner().unwrap() -//! ``` -//! -//! In case you specifically want to have a reproducible stream of "random" -//! data (e.g. to procedurally generate a game world), select a named algorithm -//! (i.e. not [`StdRng`]/[`SmallRng`] which may be adjusted in the future), and -//! use [`SeedableRng::from_seed`] or a constructor specific to the generator -//! (e.g. [`IsaacRng::new_from_u64`]). -//! -//! ## Applying / converting random data -//! -//! The [`RngCore`] trait allows generators to implement a common interface for -//! retrieving random data, but how should you use this? Typically users should -//! use the [`Rng`] trait not [`RngCore`]; this provides more flexible ways to -//! access the same data (e.g. `gen()` can output many more types than -//! `next_u32()` and `next_u64()`; Rust's optimiser should eliminate any -//! overhead). It also provides several useful algorithms, -//! e.g. `gen_bool(p)` to generate events with weighted probability and -//! `shuffle(&mut v[..])` to randomly-order a vector. -//! -//! The [`distributions`] module provides several more ways to convert random -//! data to useful values, e.g. time of decay is often modelled with an -//! exponential distribution, and the log-normal distribution provides a good -//! model of many natural phenomona. -//! -//! The [`seq`] module has a few tools applicable to sliceable or iterable data. -//! -//! ## Cryptographic security -//! -//! First, lets recap some terminology: +//! - [`Rng::sample_iter`] allows iterating over values from a chosen +//! distribution. +//! - [`Rng::gen_bool`] generates boolean "events" with a given probability. +//! - [`Rng::fill`] and [`Rng::try_fill`] are fast alternatives to fill a slice +//! of integers. +//! - [`Rng::shuffle`] randomly shuffles elements in a slice. +//! - [`Rng::choose`] picks one element at random from a slice. //! -//! - **PRNG:** *Pseudo-Random-Number-Generator* is another name for an -//! *algorithmic generator* -//! - **CSPRNG:** a *Cryptographically Secure* PRNG +//! For more slice/sequence related functionality, look in the [`seq` module]. +//! +//! There is also [`distributions::WeightedChoice`], which can be used to pick +//! elements at random with some probability. But it does not work well at the +//! moment and is going through a redesign. +//! +//! +//! # Error handling +//! +//! Error handling in Rand is a compromise between simplicity and necessity. +//! Most RNGs and sampling functions will never produce errors, and making these +//! able to handle errors would add significant overhead (to code complexity +//! and ergonomics of usage at least, and potentially also performance, +//! depending on the approach). +//! However, external RNGs can fail, and being able to handle this is important. +//! +//! It has therefore been decided that *most* methods should not return a +//! `Result` type, with as exceptions [`Rng::try_fill`], +//! [`RngCore::try_fill_bytes`], and [`SeedableRng::from_rng`]. +//! +//! Note that it is the RNG that panics when it fails but is not used through a +//! method that can report errors. Currently Rand contains only three RNGs that +//! can return an error (and thus may panic), and documents this property: +//! [`OsRng`], [`EntropyRng`] and [`ReadRng`]. Other RNGs, like [`ThreadRng`] +//! and [`StdRng`], can be used with all methods without concern. +//! +//! One further problem is that if Rand is unable to get any external randomness +//! when initializing an RNG with [`EntropyRng`], it will panic in +//! [`FromEntropy::from_entropy`], and notably in [`thread_rng`]. Except by +//! compromising security, this problem is as unsolvable as running out of +//! memory. //! -//! Security analysis requires a threat model and expert review; we can provide -//! neither, but we can provide a few hints. We assume that the goal is to -//! produce secret apparently-random data. Therefore, we need: -//! -//! - A good source of entropy. A known algorithm given known input data is -//! trivial to predict, and likewise if there's a non-negligable chance that -//! the input to a PRNG is guessable then there's a chance its output is too. -//! We recommend seeding CSPRNGs with [`EntropyRng`] or [`OsRng`] which -//! provide fresh "random" values from an external source. -//! One can also seed from another CSPRNG, e.g. `thread_rng`, which is faster, -//! but adds another component which must be trusted. -//! - A strong algorithmic generator. It is possible to use a good entropy -//! source like `OsRng` directly, and in some cases this is the best option, -//! but for better performance (or if requiring reproducible values generated -//! from a fixed seed) it is common to use a local CSPRNG. The basic security -//! that CSPRNGs must provide is making it infeasible to predict future output -//! given a sample of past output. A further security that *some* CSPRNGs -//! provide is *forward secrecy*; this ensures that in the event that the -//! algorithm's state is revealed, it is infeasible to reconstruct past -//! output. See the [`CryptoRng`] trait and notes on individual algorithms. -//! - To be careful not to leak secrets like keys and CSPRNG's internal state -//! and robust against "side channel attacks". This goes well beyond the scope -//! of random number generation, but this crate takes some precautions: -//! - to avoid printing CSPRNG state in log files, implementations have a -//! custom `Debug` implementation which omits all internal state -//! - `thread_rng` uses [`ReseedingRng`] to periodically refresh its state -//! - in the future we plan to add some protection against fork attacks -//! (where the process is forked and each clone generates the same "random" -//! numbers); this is not yet implemented (see issues #314, #370) -//! -//! # Examples +//! +//! # Distinction between Rand and `rand_core` +//! +//! The [`rand_core`] crate provides the necessary traits and functionality for +//! implementing RNGs; this includes the [`RngCore`] and [`SeedableRng`] traits +//! and the [`Error`] type. +//! Crates implementing RNGs should depend on [`rand_core`]. +//! +//! Applications and libraries consuming random values are encouraged to use the +//! Rand crate, which re-exports the common parts of [`rand_core`]. +//! +//! +//! # More examples //! //! For some inspiration, see the examples: -//! -//! * [Monte Carlo estimation of π]( -//! https://github.com/rust-lang-nursery/rand/blob/master/examples/monte-carlo.rs) -//! * [Monty Hall Problem]( -//! https://github.com/rust-lang-nursery/rand/blob/master/examples/monty-hall.rs) //! -//! [`Rng`]: trait.Rng.html -//! [`Rng::gen()`]: trait.Rng.html#method.gen -//! [`RngCore`]: trait.RngCore.html -//! [`FromEntropy`]: trait.FromEntropy.html -//! [`SeedableRng::from_seed`]: trait.SeedableRng.html#tymethod.from_seed -//! [`from_rng`]: trait.SeedableRng.html#method.from_rng -//! [`CryptoRng`]: trait.CryptoRng.html -//! [`thread_rng`]: fn.thread_rng.html +//! - [Monte Carlo estimation of π]( +//! https://github.com/rust-lang-nursery/rand/blob/master/examples/monte-carlo.rs) +//! - [Monty Hall Problem]( +//! https://github.com/rust-lang-nursery/rand/blob/master/examples/monty-hall.rs) +//! +//! +//! [`distributions` module]: distributions/index.html +//! [`distributions::WeightedChoice`]: distributions/struct.WeightedChoice.html //! [`EntropyRng`]: rngs/struct.EntropyRng.html +//! [`Error`]: struct.Error.html +//! [`gen_range`]: trait.Rng.html#method.gen_range +//! [`gen`]: trait.Rng.html#method.gen //! [`OsRng`]: rngs/struct.OsRng.html -//! [`JitterRng`]: rngs/struct.JitterRng.html -//! [`StdRng`]: rngs/struct.StdRng.html +//! [prelude]: prelude/index.html +//! [`rand_core`]: https://crates.io/crates/rand_core +//! [`random()`]: fn.random.html +//! [`ReadRng`]: rngs/adapter/struct.ReadRng.html +//! [`Rng::choose`]: trait.Rng.html#method.choose +//! [`Rng::fill`]: trait.Rng.html#method.fill +//! [`Rng::gen_bool`]: trait.Rng.html#method.gen_bool +//! [`Rng::gen`]: trait.Rng.html#method.gen +//! [`Rng::sample_iter`]: trait.Rng.html#method.sample_iter +//! [`Rng::shuffle`]: trait.Rng.html#method.shuffle +//! [`RngCore`]: trait.RngCore.html +//! [`RngCore::try_fill_bytes`]: trait.RngCore.html#method.try_fill_bytes +//! [`rngs` module]: rngs/index.html +//! [`prng` module]: prng/index.html +//! [`Rng`]: trait.Rng.html +//! [`Rng::try_fill`]: trait.Rng.html#method.try_fill +//! [`sample`]: trait.Rng.html#method.sample +//! [`SeedableRng`]: trait.SeedableRng.html +//! [`SeedableRng::from_rng`]: trait.SeedableRng.html#method.from_rng +//! [`seq` module]: seq/index.html //! [`SmallRng`]: rngs/struct.SmallRng.html -//! [`ReseedingRng`]: rngs/adapter/struct.ReseedingRng.html -//! [`prng`]: prng/index.html -//! [`IsaacRng::new_from_u64`]: prng/isaac/struct.IsaacRng.html#method.new_from_u64 -//! [`Hc128Rng`]: prng/hc128/struct.Hc128Rng.html -//! [`ChaChaRng`]: prng/chacha/struct.ChaChaRng.html -//! [`IsaacRng`]: prng/isaac/struct.IsaacRng.html -//! [`Isaac64Rng`]: prng/isaac64/struct.Isaac64Rng.html -//! [`seq`]: seq/index.html -//! [`distributions`]: distributions/index.html +//! [`StdRng`]: rngs/struct.StdRng.html +//! [`thread_rng()`]: fn.thread_rng.html +//! [`ThreadRng`]: rngs/struct.ThreadRng.html //! [`Standard`]: distributions/struct.Standard.html +//! [`Uniform`]: distributions/struct.Uniform.html + #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png", html_favicon_url = "https://www.rust-lang.org/favicon.ico", @@ -291,7 +345,7 @@ pub trait Rand : Sized { /// /// Example: /// -/// ```rust +/// ``` /// # use rand::thread_rng; /// use rand::Rng; /// @@ -310,7 +364,7 @@ pub trait Rng: RngCore { /// /// # Example /// - /// ```rust + /// ``` /// use rand::{thread_rng, Rng}; /// /// let mut rng = thread_rng(); @@ -318,6 +372,7 @@ pub trait Rng: RngCore { /// println!("{}", x); /// println!("{:?}", rng.gen::<(f64, bool)>()); /// ``` + #[inline] fn gen(&mut self) -> T where Standard: Distribution { Standard.sample(self) } @@ -338,7 +393,7 @@ pub trait Rng: RngCore { /// /// # Example /// - /// ```rust + /// ``` /// use rand::{thread_rng, Rng}; /// /// let mut rng = thread_rng(); @@ -359,7 +414,7 @@ pub trait Rng: RngCore { /// /// ### Example /// - /// ```rust + /// ``` /// use rand::{thread_rng, Rng}; /// use rand::distributions::Uniform; /// @@ -377,7 +432,7 @@ pub trait Rng: RngCore { /// /// # Example /// - /// ```rust + /// ``` /// use rand::{thread_rng, Rng}; /// use rand::distributions::{Alphanumeric, Uniform, Standard}; /// @@ -419,7 +474,7 @@ pub trait Rng: RngCore { /// /// # Example /// - /// ```rust + /// ``` /// use rand::{thread_rng, Rng}; /// /// let mut arr = [0i8; 20]; @@ -448,7 +503,7 @@ pub trait Rng: RngCore { /// /// # Example /// - /// ```rust + /// ``` /// # use rand::Error; /// use rand::{thread_rng, Rng}; /// @@ -477,7 +532,7 @@ pub trait Rng: RngCore { /// /// # Example /// - /// ```rust + /// ``` /// use rand::{thread_rng, Rng}; /// /// let mut rng = thread_rng(); @@ -537,7 +592,7 @@ pub trait Rng: RngCore { /// /// # Example /// - /// ```rust + /// ``` /// use rand::{thread_rng, Rng}; /// /// let mut rng = thread_rng(); @@ -582,7 +637,7 @@ pub trait Rng: RngCore { /// /// # Example /// - /// ```rust + /// ``` /// # #![allow(deprecated)] /// use rand::{thread_rng, Rng}; /// @@ -605,7 +660,7 @@ pub trait Rng: RngCore { /// /// # Example /// - /// ```rust + /// ``` /// # #![allow(deprecated)] /// use rand::{thread_rng, Rng}; /// @@ -799,10 +854,12 @@ pub trait FromEntropy: SeedableRng { /// applications targetting PC/mobile platforms should not need to worry /// about this failing. /// + /// # Panics + /// /// If all entropy sources fail this will panic. If you need to handle /// errors, use the following code, equivalent aside from error handling: /// - /// ```rust + /// ``` /// # use rand::Error; /// use rand::prelude::*; /// use rand::rngs::EntropyRng; @@ -856,7 +913,7 @@ pub fn weak_rng() -> XorShiftRng { /// /// # Examples /// -/// ```rust +/// ``` /// let x = rand::random::(); /// println!("{}", x); /// @@ -871,7 +928,7 @@ pub fn weak_rng() -> XorShiftRng { /// If you're calling `random()` in a loop, caching the generator as in the /// following example can increase performance. /// -/// ```rust +/// ``` /// # #![allow(deprecated)] /// use rand::Rng; /// @@ -893,6 +950,7 @@ pub fn weak_rng() -> XorShiftRng { /// [`thread_rng`]: fn.thread_rng.html /// [`Standard`]: distributions/struct.Standard.html #[cfg(feature="std")] +#[inline] pub fn random() -> T where Standard: Distribution { thread_rng().gen() } @@ -904,7 +962,7 @@ pub fn random() -> T where Standard: Distribution { /// /// # Example /// -/// ```rust +/// ``` /// # #![allow(deprecated)] /// use rand::{thread_rng, sample}; /// @@ -913,6 +971,7 @@ pub fn random() -> T where Standard: Distribution { /// println!("{:?}", sample); /// ``` #[cfg(feature="std")] +#[inline] #[deprecated(since="0.4.0", note="renamed to seq::sample_iter")] pub fn sample(rng: &mut R, iterable: I, amount: usize) -> Vec where I: IntoIterator, diff --git a/src/prng/chacha.rs b/src/prng/chacha.rs index 4ee206114a0..c81af624737 100644 --- a/src/prng/chacha.rs +++ b/src/prng/chacha.rs @@ -112,7 +112,7 @@ impl ChaChaRng { /// /// # Examples /// - /// ```rust + /// ``` /// # #![allow(deprecated)] /// use rand::{RngCore, ChaChaRng}; /// diff --git a/src/prng/hc128.rs b/src/prng/hc128.rs index 794565bac88..733975c7b77 100644 --- a/src/prng/hc128.rs +++ b/src/prng/hc128.rs @@ -40,7 +40,7 @@ const SEED_WORDS: usize = 8; // 128 bit key followed by 128 bit iv /// current state of known attacks / weaknesses of HC-128 is given in [4]. /// /// The average cycle length is expected to be -/// 21024*32-1 = 232767. +/// 21024*32+10-1 = 232777. /// We support seeding with a 256-bit array, which matches the 128-bit key /// concatenated with a 128-bit IV from the stream cipher. /// @@ -50,7 +50,7 @@ const SEED_WORDS: usize = 8; // 128 bit key followed by 128 bit iv /// ## References /// [1]: Hongjun Wu (2008). ["The Stream Cipher HC-128"]( /// http://www.ecrypt.eu.org/stream/p3ciphers/hc/hc128_p3.pdf). -/// *The eSTREAM Finalists*, LNCS 4986, pp. 39--47, Springer-Verlag. +/// *The eSTREAM Finalists*, LNCS 4986, pp. 39–47, Springer-Verlag. /// /// [2]: [eSTREAM: the ECRYPT Stream Cipher Project]( /// http://www.ecrypt.eu.org/stream/) diff --git a/src/prng/isaac.rs b/src/prng/isaac.rs index 42b78a94d02..db4a7361d41 100644 --- a/src/prng/isaac.rs +++ b/src/prng/isaac.rs @@ -72,7 +72,7 @@ const RAND_SIZE: usize = 1 << RAND_SIZE_LEN; /// runs once every 256 times you ask for a next random number. In all other /// circumstances the last element of the results array is returned. /// -/// ISAAC therefore needs a lot of memory, relative to other non-vrypto RNGs. +/// ISAAC therefore needs a lot of memory, relative to other non-crypto RNGs. /// 2 * 256 * 4 = 2 kb to hold the state and results. /// /// This implementation uses [`BlockRng`] to implement the [`RngCore`] methods. @@ -167,7 +167,7 @@ impl BlockRngCore for IsaacCore { type Results = IsaacArray; /// Refills the output buffer, `results`. See also the pseudocode desciption - /// of the algorithm in the [`Isaac64Rng`] documentation. + /// of the algorithm in the [`IsaacRng`] documentation. /// /// Optimisations used (similar to the reference implementation): /// diff --git a/src/prng/mod.rs b/src/prng/mod.rs index c4bd0032052..240b6828b4f 100644 --- a/src/prng/mod.rs +++ b/src/prng/mod.rs @@ -8,37 +8,312 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Pseudo random number generators are algorithms to produce *apparently -//! random* numbers deterministically, and usually fairly quickly. -//! -//! So long as the algorithm is computationally secure, is initialised with -//! sufficient entropy (i.e. unknown by an attacker), and its internal state is -//! also protected (unknown to an attacker), the output will also be -//! *computationally secure*. Computationally Secure Pseudo Random Number -//! Generators (CSPRNGs) are thus suitable sources of random numbers for -//! cryptography. There are a couple of gotchas here, however. First, the seed -//! used for initialisation must be unknown. Usually this should be provided by -//! the operating system and should usually be secure, however this may not -//! always be the case (especially soon after startup). Second, user-space -//! memory may be vulnerable, for example when written to swap space, and after -//! forking a child process should reinitialise any user-space PRNGs. For this -//! reason it may be preferable to source random numbers directly from the OS -//! for cryptographic applications. -//! -//! PRNGs are also widely used for non-cryptographic uses: randomised -//! algorithms, simulations, games. In these applications it is usually not -//! important for numbers to be cryptographically *unguessable*, but even -//! distribution and independence from other samples (from the point of view -//! of someone unaware of the algorithm used, at least) may still be important. -//! Good PRNGs should satisfy these properties, but do not take them for -//! granted; Wikipedia's article on -//! [Pseudorandom number generators](https://en.wikipedia.org/wiki/Pseudorandom_number_generator) -//! provides some background on this topic. -//! -//! Care should be taken when seeding (initialising) PRNGs. Some PRNGs have -//! short periods for some seeds. If one PRNG is seeded from another using the -//! same algorithm, it is possible that both will yield the same sequence of -//! values (with some lag). +//! Pseudo-random number generators. +//! +//! Pseudo-random number generators are algorithms to produce apparently random +//! numbers deterministically, and usually fairly quickly. See the documentation +//! of the [`rngs` module] for some introduction to PRNGs. +//! +//! As mentioned there, PRNGs fall in two broad categories: +//! +//! - [basic PRNGs], primarily designed for simulations +//! - [CSPRNGs], primarily designed for cryptography +//! +//! In simple terms, the basic PRNGs are often predictable; CSPRNGs should not +//! be predictable *when used correctly*. +//! +//! Contents of this documentation: +//! +//! 1. [The generators](#the-generators) +//! 1. [Performance and size](#performance) +//! 1. [Quality and cycle length](#quality) +//! 1. [Security](#security) +//! 1. [Extra features](#extra-features) +//! 1. [Further reading](#further-reading) +//! +//! +//! # The generators +//! +//! ## Basic pseudo-random number generators (PRNGs) +//! +//! The goal of regular, non-cryptographic PRNGs is usually to find a good +//! balance between simplicity, quality, memory usage and performance. These +//! algorithms are very important to Monte Carlo simulations, and also suitable +//! for several other problems such as randomized algorithms and games (except +//! where there is a risk of players predicting the next output value from +//! previous values, in which case a CSPRNG should be used). +//! +//! Currently Rand provides only one PRNG, and not a very good one at that: +//! +//! | name | full name | performance | memory | quality | period | features | +//! |------|-----------|-------------|--------|---------|--------|----------| +//! | [`XorShiftRng`] | Xorshift 32/128 | ★★★☆☆ | 16 bytes | ★☆☆☆☆ | `u32` * 2128 - 1 | — | +//! +// Quality stars [not rendered in documentation]: +// 5. reserved for crypto-level (e.g. ChaCha8, ISAAC) +// 4. good performance on TestU01 and PractRand, good theory +// (e.g. PCG, truncated Xorshift*) +// 3. good performance on TestU01 and PractRand, but "falling through the +// cracks" or insufficient theory (e.g. SFC, Xoshiro) +// 2. imperfect performance on tests or other limiting properties, but not +// terrible (e.g. Xoroshiro128+) +// 1. clear deficiencies in test results, cycle length, theory, or other +// properties (e.g. Xorshift) +// +// Performance stars [not rendered in documentation]: +// Meant to give an indication of relative performance. Roughly follows a log +// scale, based on the performance of `next_u64` on a current i5/i7: +// - 5. 8000 MB/s+ +// - 4. 4000 MB/s+ +// - 3. 2000 MB/s+ +// - 2. 1000 MB/s+ +// - 1. < 1000 MB/s +// +//! ## Cryptographically secure pseudo-random number generators (CSPRNGs) +//! +//! CSPRNGs have much higher requirements than basic PRNGs. The primary +//! consideration is security. Performance and simplicity are also important, +//! but in general CSPRNGs are more complex and slower than regular PRNGs. +//! Quality is no longer a concern, as it is a requirement for a +//! CSPRNG that the output is basically indistinguishable from true randomness +//! since any bias or correlation makes the output more predictable. +//! +//! There is a close relationship between CSPRNGs and cryptographic ciphers. +//! Any block cipher can be turned into a CSPRNG by encrypting a counter. Stream +//! ciphers are basically a CSPRNG and a combining operation, usually XOR. This +//! means that we can easily use any stream cipher as a CSPRNG. +//! +//! Rand currently provides two trustworthy CSPRNGs and two CSPRNG-like PRNGs: +//! +//! | name | full name | performance | initialization | memory | predictability | forward secrecy | +//! |------|-----------|--------------|--------------|----------|----------------|-------------------------| +//! | [`ChaChaRng`] | ChaCha20 | ★☆☆☆☆ | fast | 136 bytes | secure | no | +//! | [`Hc128Rng`] | HC-128 | ★★☆☆☆ | slow | 4176 bytes | secure | no | +//! | [`IsaacRng`] | ISAAC | ★★☆☆☆ | slow | 2072 bytes | unknown | unknown | +//! | [`Isaac64Rng`] | ISAAC-64 | ★★☆☆☆ | slow | 4136 bytes| unknown | unknown | +//! +//! It should be noted that the ISAAC generators are only included for +//! historical reasons, they have been with the Rust language since the very +//! beginning. They have good quality output and no attacks are known, but have +//! received little attention from cryptography experts. +//! +//! +//! # Performance +//! +//! First it has to be said most PRNGs are very fast, and will rarely be a +//! performance bottleneck. +//! +//! Performance of basic PRNGs is a bit of a subtle thing. It depends a lot on +//! the CPU architecture (32 vs. 64 bits), inlining, and also on the number of +//! available registers. This often causes the performance to be affected by +//! surrounding code due to inlining and other usage of registers. +//! +//! When choosing a PRNG for performance it is important to benchmark your own +//! application due to interactions between PRNGs and surrounding code and +//! dependence on the CPU architecture as well as the impact of the size of +//! data requested. Because of all this, we do not include performance numbers +//! here but merely a qualitative rating. +//! +//! CSPRNGs are a little different in that they typically generate a block of +//! output in a cache, and pull outputs from the cache. This allows them to have +//! good amortised performance, and reduces or completely removes the influence +//! of surrounding code on the CSPRNG performance. +//! +//! ### Worst-case performance +//! Because CSPRNGs usually produce a block of values into a cache, they have +//! poor worst case performance (in contrast to basic PRNGs, where the +//! performance is usually quite regular). +//! +//! ## State size +//! +//! Simple PRNGs often use very little memory, commonly only a few words, where +//! a *word* is usually either `u32` or `u64`. This is not true for all +//! non-cryptographic PRNGs however, for example the historically popular +//! Mersenne Twister MT19937 algorithm requires 2.5 kB of state. +//! +//! CSPRNGs typically require more memory; since the seed size is recommended +//! to be at least 192 bits and some more may be required for the algorithm, +//! 256 bits would be approximately the minimum secure size. In practice, +//! CSPRNGs tend to use quite a bit more, [`ChaChaRng`] is relatively small with +//! 136 bytes of state. +//! +//! ## Initialization time +//! +//! The time required to initialize new generators varies significantly. Many +//! simple PRNGs and even some cryptographic ones (including [`ChaChaRng`]) +//! only need to copy the seed value and some constants into their state, and +//! thus can be constructed very quickly. In contrast, CSPRNGs with large state +//! require an expensive key-expansion. +//! +//! # Quality +//! +//! Many basic PRNGs are not much more than a couple of bitwise and arithmetic +//! operations. Their simplicity gives good performance, but also means there +//! are small regularities hidden in the generated random number stream. +//! +//! How much do those hidden regularities matter? That is hard to say, and +//! depends on how the RNG gets used. If there happen to be correlations between +//! the random numbers and the algorithm they are used in, the results can be +//! wrong or misleading. +//! +//! A random number generator can be considered good if it gives the correct +//! results in as many applications as possible. The quality of PRNG +//! algorithms can be evaluated to some extend analytically, to determine the +//! cycle length and to rule out some correlations. Then there are empirical +//! test suites designed to test how well a PRNG performs on a wide range of +//! possible uses, the latest and most complete of which are [TestU01] and +//! [PractRand]. +//! +//! CSPRNGs tend to be more complex, and have an explicit requirement to be +//! unpredictable. This implies there must be no obvious correlations between +//! output values. +//! +//! ### Quality stars: +//! PRNGs with 3 stars or more should be good enough for any purpose. +//! 1 or 2 stars may be good enough for typical apps and games, but do not work +//! well with all algorithms. +//! +//! ## Period +//! +//! The *period* or *cycle length* of a PRNG is the number of values that can be +//! generated after which it starts repeating the same random number stream. +//! Many PRNGs have a fixed-size period, but for some only an expected average +//! cycle length can be given, where the exact length depends on the seed. +//! +//! On today's hardware, even a fast RNG with a cycle length of *only* +//! 264 can be used for centuries before cycling. Yet we recommend a +//! period of 2128 or more, which most modern PRNGs satisfy. +//! Alternatively a PRNG with shorter period but support for multiple streams +//! may be chosen. There are two reasons for this, as follows. +//! +//! If we see the entire period of an RNG as one long random number stream, +//! every independently seeded RNG returns a slice of that stream. When multiple +//! RNG are seeded randomly, there is an increasingly large chance to end up +//! with a partially overlapping slice of the stream. +//! +//! If the period of the RNG is 2128, and an application consumes +//! 248 values, it then takes about 232 random +//! initializations to have a chance of 1 in a million to repeat part of an +//! already used stream. This seems good enough for common usage of +//! non-cryptographic generators, hence the recommendation of at least +//! 2128. As an estimate, the chance of any overlap in a period of +//! size `p` with `n` independent seeds and `u` values used per seed is +//! approximately `1 - e^(-u * n^2 / (2 * p))`. +//! +//! Further, it is not recommended to use the full period of an RNG. Many +//! PRNGs have a property called *k-dimensional equidistribution*, meaning that +//! for values of some size (potentially larger than the output size), all +//! possible values are produced the same number of times over the generator's +//! period. This is not a property of true randomness. This is known as the +//! generalized birthday problem, see the [PCG paper] for a good explanation. +//! This results in a noticable bias on output after generating more values +//! than the square root of the period (after 264 values for a +//! period of 2128). +//! +//! +//! # Security +//! +//! ## Predictability +//! +//! From the context of any PRNG, one can ask the question *given some previous +//! output from the PRNG, is it possible to predict the next output value?* +//! This is an important property in any situation where there might be an +//! adversary. +//! +//! Regular PRNGs tend to be predictable, although with varying difficulty. In +//! some cases prediction is trivial, for example plain Xorshift outputs part of +//! its state without mutation, and prediction is as simple as seeding a new +//! Xorshift generator from four `u32` outputs. Other generators, like +//! [PCG](http://www.pcg-random.org/predictability.html) and truncated Xorshift* +//! are harder to predict, but not outside the realm of common mathematics and a +//! desktop PC. +//! +//! The basic security that CSPRNGs must provide is the infeasibility to predict +//! output. This requirement is formalized as the [next-bit test]; this is +//! roughly stated as: given the first *k* bits of a random sequence, the +//! sequence satisfies the next-bit test if there is no algorithm able to +//! predict the next bit using reasonable computing power. +//! +//! A further security that *some* CSPRNGs provide is forward secrecy: +//! in the event that the CSPRNGs state is revealed at some point, it must be +//! infeasible to reconstruct previous states or output. Note that many CSPRNGs +//! *do not* have forward secrecy in their usual formulations. +//! +//! As an outsider it is hard to get a good idea about the security of an +//! algorithm. People in the field of cryptography spend a lot of effort +//! analyzing existing designs, and what was once considered good may now turn +//! out to be weaker. Generally it is best to use algorithms well-analyzed by +//! experts, such as those recommended by NIST or ECRYPT. +//! +//! ## State and seeding +//! +//! It is worth noting that a CSPRNG's security relies absolutely on being +//! seeded with a secure random key. Should the key be known or guessable, all +//! output of the CSPRNG is easy to guess. This implies that the seed should +//! come from a trusted source; usually either the OS or another CSPRNG. Our +//! seeding helper trait, [`FromEntropy`], and the source it uses +//! ([`EntropyRng`]), should be secure. Additionally, [`ThreadRng`] is a CSPRNG, +//! thus it is acceptable to seed from this (although for security applications +//! fresh/external entropy should be preferred). +//! +//! Further, it should be obvious that the internal state of a CSPRNG must be +//! kept secret. With that in mind, our implementations do not provide direct +//! access to most of their internal state, and `Debug` implementations do not +//! print any internal state. This does not fully protect CSPRNG state; code +//! within the same process may read this memory (and we allow cloning and +//! serialisation of CSPRNGs for convenience). Further, a running process may be +//! forked by the operating system, which may leave both processes with a copy +//! of the same generator. +//! +//! ## Not a crypto library +//! +//! It should be emphasised that this is not a cryptography library; although +//! Rand does take some measures to provide secure random numbers, it does not +//! necessarily take all recommended measures. Further, cryptographic processes +//! such as encryption and authentication are complex and must be implemented +//! very carefully to avoid flaws and resist known attacks. It is therefore +//! recommended to use specialized libraries where possible, for example +//! [openssl], [ring] and the [RustCrypto libraries]. +//! +//! +//! # Extra features +//! +//! Some PRNGs may provide extra features, like: +//! +//! - Support for multiple streams, which can help with parallel tasks. +//! - The ability to jump or seek around in the random number stream; +//! with large periood this can be used as an alternative to streams. +//! +//! +//! # Further reading +//! +//! There is quite a lot that can be said about PRNGs. The [PCG paper] is a +//! very approachable explaining more concepts. +//! +//! A good paper about RNG quality is +//! ["Good random number generators are (not so) easy to find"]( +//! http://random.mat.sbg.ac.at/results/peter/A19final.pdf) by P. Hellekalek. +//! +//! +//! [`rngs` module]: ../rngs/index.html +//! [basic PRNGs]: #basic-pseudo-random-number-generators-prngs +//! [CSPRNGs]: #cryptographically-secure-pseudo-random-number-generators-csprngs +//! [`XorShiftRng`]: struct.XorShiftRng.html +//! [`ChaChaRng`]: chacha/struct.ChaChaRng.html +//! [`Hc128Rng`]: hc128/struct.Hc128Rng.html +//! [`IsaacRng`]: isaac/struct.IsaacRng.html +//! [`Isaac64Rng`]: isaac64/struct.Isaac64Rng.html +//! [`ThreadRng`]: ../rngs/struct.ThreadRng.html +//! [`FromEntropy`]: ../trait.FromEntropy.html +//! [`EntropyRng`]: ../rngs/struct.EntropyRng.html +//! [TestU01]: http://simul.iro.umontreal.ca/testu01/tu01.html +//! [PractRand]: http://pracrand.sourceforge.net/ +//! [PCG paper]: http://www.pcg-random.org/pdf/hmc-cs-2014-0905.pdf +//! [openssl]: https://crates.io/crates/openssl +//! [ring]: https://crates.io/crates/ring +//! [RustCrypto libraries]: https://github.com/RustCrypto +//! [next-bit test]: https://en.wikipedia.org/wiki/Next-bit_test + pub mod chacha; pub mod hc128; diff --git a/src/rngs/adapter/read.rs b/src/rngs/adapter/read.rs index b0bfd7a534d..de75f978cd3 100644 --- a/src/rngs/adapter/read.rs +++ b/src/rngs/adapter/read.rs @@ -27,12 +27,12 @@ use rand_core::{RngCore, Error, ErrorKind, impls}; /// /// `ReadRng` uses `std::io::read_exact`, which retries on interrupts. All other /// errors from the underlying reader, including when it does not have enough -/// data, will only be reported through `try_fill_bytes`. The other `RngCore` -/// methods will panic in case of an error error. +/// data, will only be reported through [`try_fill_bytes`]. The other +/// [`RngCore`] methods will panic in case of an error. /// /// # Example /// -/// ```rust +/// ``` /// use rand::{read, Rng}; /// /// let data = vec![1, 2, 3, 4, 5, 6, 7, 8]; @@ -41,6 +41,8 @@ use rand_core::{RngCore, Error, ErrorKind, impls}; /// ``` /// /// [`OsRng`]: ../struct.OsRng.html +/// [`RngCore`]: ../../trait.RngCore.html +/// [`try_fill_bytes`]: ../../trait.RngCore.html#method.tymethod.try_fill_bytes #[derive(Debug)] pub struct ReadRng { reader: R diff --git a/src/rngs/entropy.rs b/src/rngs/entropy.rs index d500bc1d832..e260af9cb17 100644 --- a/src/rngs/entropy.rs +++ b/src/rngs/entropy.rs @@ -15,12 +15,12 @@ use rngs::{OsRng, JitterRng}; /// An interface returning random data from external source(s), provided /// specifically for securely seeding algorithmic generators (PRNGs). -/// +/// /// Where possible, `EntropyRng` retrieves random data from the operating /// system's interface for random numbers ([`OsRng`]); if that fails it will /// fall back to the [`JitterRng`] entropy collector. In the latter case it will /// still try to use [`OsRng`] on the next usage. -/// +/// /// If no secure source of entropy is available `EntropyRng` will panic on use; /// i.e. it should never output predictable data. /// @@ -30,9 +30,20 @@ use rngs::{OsRng, JitterRng}; /// external entropy then primarily use the local PRNG ([`thread_rng`] is /// provided as a convenient, local, automatically-seeded CSPRNG). /// +/// # Panics +/// +/// On most systems, like Windows, Linux, macOS and *BSD on common hardware, it +/// is highly unlikely for both [`OsRng`] and [`JitterRng`] to fail. But on +/// combinations like webassembly without Emscripten or stdweb both sources are +/// unavailable. If both sources fail, only [`try_fill_bytes`] is able to +/// report the error, and only the one from `OsRng`. The other [`RngCore`] +/// methods will panic in case of an error. +/// /// [`OsRng`]: struct.OsRng.html /// [`JitterRng`]: jitter/struct.JitterRng.html /// [`thread_rng`]: ../fn.thread_rng.html +/// [`RngCore`]: ../trait.RngCore.html +/// [`try_fill_bytes`]: ../trait.RngCore.html#method.tymethod.try_fill_bytes #[derive(Debug)] pub struct EntropyRng { rng: EntropySource, diff --git a/src/rngs/jitter.rs b/src/rngs/jitter.rs index 63139ca7bb1..a31a1df67e3 100644 --- a/src/rngs/jitter.rs +++ b/src/rngs/jitter.rs @@ -311,7 +311,7 @@ impl JitterRng { /// /// # Example /// - /// ```rust + /// ``` /// # use rand::{Rng, Error}; /// use rand::jitter::JitterRng; /// diff --git a/src/rngs/mock.rs b/src/rngs/mock.rs index 3651e04776b..812e4bebfdb 100644 --- a/src/rngs/mock.rs +++ b/src/rngs/mock.rs @@ -18,7 +18,7 @@ use rand_core::{RngCore, Error, impls}; /// over a `u64` number, using wrapping arithmetic. If the increment is 0 /// the generator yields a constant. /// -/// ```rust +/// ``` /// use rand::Rng; /// use rand::rngs::mock::StepRng; /// diff --git a/src/rngs/os.rs b/src/rngs/os.rs index 96b8d90f85b..2239d4577ea 100644 --- a/src/rngs/os.rs +++ b/src/rngs/os.rs @@ -65,7 +65,16 @@ use rand_core::{CryptoRng, RngCore, Error, impls}; /// error. Because we keep one file descriptor to `/dev/urandom` open when /// succesful, this is only a small one-time cost. /// +/// # Panics +/// +/// `OsRng` is extremely unlikely to fail if `OsRng::new()` was succesfull. But +/// in case it does fail, only [`try_fill_bytes`] is able to report the cause. +/// Depending on the error the other [`RngCore`] methods will retry several +/// times, and panic in case the error remains. +/// /// [`EntropyRng`]: struct.EntropyRng.html +/// [`RngCore`]: ../trait.RngCore.html +/// [`try_fill_bytes`]: ../trait.RngCore.html#method.tymethod.try_fill_bytes #[allow(unused)] // not used by all targets diff --git a/src/seq.rs b/src/seq.rs index 1a128ced567..68f7ab08edc 100644 --- a/src/seq.rs +++ b/src/seq.rs @@ -32,7 +32,7 @@ use super::Rng; /// /// # Example /// -/// ```rust +/// ``` /// use rand::{thread_rng, seq}; /// /// let mut rng = thread_rng(); @@ -77,7 +77,7 @@ pub fn sample_iter(rng: &mut R, iterable: I, amount: usize) -> Result(rng: &mut R, slice: &[T], amount: usize) -> Vec /// /// # Example /// -/// ```rust +/// ``` /// use rand::{thread_rng, seq}; /// /// let mut rng = thread_rng();