diff --git a/src/SUMMARY.md b/src/SUMMARY.md index c75cd7f..25ed260 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -2,14 +2,15 @@ [Introduction](intro.md) -- [Getting Started](guide-start.md) +- [Quick start](quick-start.md) -- [Crates and features](crates.md) - - [Rand and co](crates-rand.md) - - [Random generators](crates-gen.md) +- [Crates](crates.md) + - [Features](crate-features.md) + - [Platform support](crate-platforms.md) + - [Reproducibility](crate-reprod.md) - [Guide](guide.md) - - [Cargo and features](guide-cargo.md) + - [Getting started](guide-start.md) - [Random data](guide-data.md) - [Types of generators](guide-gen.md) - [Our RNGs](guide-rngs.md) @@ -21,8 +22,6 @@ - [Sequences](guide-seq.md) - [Error handling](guide-err.md) -- [Portability](portability.md) - - [Updating](update.md) - [Updating to 0.5](update-0.5.md) - [Updating to 0.6](update-0.6.md) diff --git a/src/crate-features.md b/src/crate-features.md new file mode 100644 index 0000000..d14dadc --- /dev/null +++ b/src/crate-features.md @@ -0,0 +1,38 @@ +# Crate features + +For definitive documentation of crate features, check the crate release's `Cargo.toml`: + +- +- +- + +## Common features + +The following features are common to `rand_core`, `rand`, `rand_distr` and potentially some RNG crates: + +- `std`: opt into functionality dependent on the `std` lib. This is default-enabled except in `rand_core`; for `no_std` usage, use `default-features = false`. +- `alloc`: enables functionality requiring an allocator (for usage with `no_std`). This is implied by `std`. +- `serde1`: enables serialization via [`serde`], version 1.0. + +## Rand features + +Additional `rand` features: + +- `small_rng` enables the [`SmallRng`] generator (feature-gated since v0.7). +- `simd_support`: Experimental support for generating various SIMD types (requires nightly `rustc`). +- `log` enables a few log messages via [`log`]. + +Note regarding SIMD: the above flag concerns explicit generation of SIMD types +only and not optimisation. SIMD operations may be used internally regardless of +this flag; e.g. the ChaCha generator has explicit support for SIMD operations +internally. + +## rand_distr features + +The floating point functions from `num_traits` and `libm` are used to support +`no_std` environments and ensure reproducibility. If the floating point +functions from `std` are preferred, which may provide better accuracy and +performance but may produce different random values, the `std_math` feature +can be enabled. (Note that any other crate depending on `num-traits`'s `std` feature (default-enabled) will have the same effect.) + +[`SmallRng`]: https://docs.rs/rand/latest/rand/rngs/struct.SmallRng.html diff --git a/src/crate-platforms.md b/src/crate-platforms.md new file mode 100644 index 0000000..e0995ca --- /dev/null +++ b/src/crate-platforms.md @@ -0,0 +1,22 @@ +# Platform support + +Thanks to many community contributions, Rand crates support a wide variety of platforms. + +## no_std + +With `default-features = false`, both `rand` and `rand_distr` support `no_std` builds. See [Common features](crate-features.html#common-features). + +## getrandom + +The [`getrandom`] crate provides a low-level API around platform-specific +random-number sources, and is an important building block of `rand` and +`rand_core` as well as a number of cryptography libraries. +It is not intended for usage outside of low-level libraries. + +### WebAssembly + +The `wasm32-unknown-unknown` target does not make any assumptions about which JavaScript interface is available, thus the `getrandom` crate requires configuration. See [WebAssembly support](https://docs.rs/getrandom/latest/getrandom/#webassembly-support). + +Note that the `wasm32-wasi` and `wasm32-unknown-emscripten` targets do not have this limitation. + +[`getrandom`]: https://docs.rs/getrandom/ diff --git a/src/portability.md b/src/crate-reprod.md similarity index 85% rename from src/portability.md rename to src/crate-reprod.md index eaa560b..2e13d4f 100644 --- a/src/portability.md +++ b/src/crate-reprod.md @@ -1,4 +1,4 @@ -# Portability +# Reproducibility ## Definitions @@ -61,7 +61,7 @@ upper bound exceeds `u32::MAX`. ### Portability of floats The results of floating point arithmetic depend on rounding modes and -implementation details. Especially the results of transcendental functions vary -from platform to platform. Due to this, the distributions in `rand_distr` are -not always portable for `f32` and `f64`. However, we strive to make them as -portable as possible. +implementation details. In particular, the results of transcendental functions vary +from platform to platform. Due to this, results of distributions in `rand_distr` using `f32` or `f64` may not be portable. + +To aleviate (or further complicate) this concern, we prefer to use `libm` over `std` implementations of these transcendental functions. See [rand_distr features](crate-features.html#rand_distr-features). diff --git a/src/crates-gen.md b/src/crates-gen.md deleted file mode 100644 index c6a8480..0000000 --- a/src/crates-gen.md +++ /dev/null @@ -1,50 +0,0 @@ -# Random Generators - -## Getrandom - -The [`getrandom`] crate provides a low-level API around platform-specific -random-number sources, and is an important building block of `rand` and -`rand_core` as well as a number of cryptography libraries. -It is not intended for usage outside of low-level libraries. - -In some cases, particularly when targeting WASM, end-users may need to -configure this crate. -Consult the [`getrandom`] documentation for the relevant version. - -## CPU Jitter - -The [`rand_jitter`] crate implements a CPU-jitter-based entropy harvester which -may be used to provide an alternative source of entropy where a high-resolution -CPU timer is available. - -It should be noted that CPU-jitter harvesters [may be prone to side-channel -attacks](https://github.com/rust-random/rand/issues/699) and that this -implementation is quite slow (due to conservative estimates of entropy gained -per step). - -In prior versions of `rand` this was a direct dependency, used -automatically when other sources of entropy failed. -In current versions it is not a dependency (not even an optional one). - - -## Deterministic generators - -The following crates implement pseudo-random number generators -(see [Our RNGs](guide-rngs.md)): - -- [`rand_chacha`] provides generators using the ChaCha cipher -- [`rand_hc`] implements a generator using the HC-128 cipher -- [`rand_isaac`] implements the ISAAC generators -- [`rand_pcg`] implements a small selection of PCG generators -- [`rand_xoshiro`] implements the SplitMix and Xoshiro generators -- [`rand_xorshift`] implements the basic Xorshift generator - - -[`rand_chacha`]: https://docs.rs/rand_chacha/ -[`rand_hc`]: https://docs.rs/rand_hc/ -[`rand_isaac`]: https://docs.rs/rand_isaac/ -[`rand_pcg`]: https://docs.rs/rand_pcg/ -[`rand_xoshiro`]: https://docs.rs/rand_xoshiro/ -[`rand_xorshift`]: https://docs.rs/rand_xorshift/ -[`rand_jitter`]: https://docs.rs/rand_jitter/ -[`getrandom`]: https://docs.rs/getrandom/ diff --git a/src/crates-rand.md b/src/crates-rand.md deleted file mode 100644 index 34db0f6..0000000 --- a/src/crates-rand.md +++ /dev/null @@ -1,69 +0,0 @@ -# Rand and co - -## rand_core (API) - -The [`rand_core`] crate defines the core traits implemented by RNGs. This exists -as a separate crate with two purposes: - -- to provide a minimal API for defining and using RNGs -- to provide tools to aid implementation of RNGs - -The [`RngCore`], [`SeedableRng`], [`CryptoRng`] traits and [`Error`] type are -all defined by this crate and re-exported by the [`rand`] crate. - -## rand (primary interface) - -The [`rand`] crate is optimised for easy usage of common random-number -functionality. This has several aspects: - -- the [`rngs`] module provides a few convenient generators -- the [`distributions`] module concerns sampling of random values -- the [`seq`] module concerns sampling from and shuffling sequences -- the [`Rng`] trait provides a few convenience methods for generating - random values -- the [`random`] function provides convenient generation in a single call - -### Feature flags - -Besides the [common feature flags], several aspects are configurable: - -- `small_rng` enables the [`SmallRng`] generator (feature-gated since v0.7) -- `simd_support` enables experimental (nightly-only) support for generating - SIMD values - -Note regarding SIMD: the above flag concerns explicit generation of SIMD types -only and not optimisation. SIMD operations may be used internally regardless of -this flag; e.g. the ChaCha generator has explicit support for SIMD operations -internally. - -## Distributions - -The [`rand`] crate only implements sampling from the most common random -number distributions: uniform and weighted sampling. For everything else, - -- [`rand_distr`] provides fast sampling from a variety of other distributions, - including Normal (Gauss), Binomial, Poisson, UnitCircle, and many more -- [`statrs`] is a port of the C# Math.NET library, implementing many of the - same distributions (plus/minus a few), along with PDF and CDF functions, - the *error*, *beta*, *gamma* and *logistic* special functions, plus a few - utilities. (For clarity, [`statrs`] is not part of the Rand library.) - -[common feature flags]: crates.md#feature-flags - -[`rand_core`]: https://docs.rs/rand_core/ -[`rand`]: https://docs.rs/rand/ -[`rand_distr`]: https://docs.rs/rand_distr/ -[`statrs`]: https://docs.rs/statrs/ - -[`RngCore`]: https://docs.rs/rand_core/latest/rand_core/trait.RngCore.html -[`SeedableRng`]: https://docs.rs/rand_core/latest/rand_core/trait.SeedableRng.html -[`CryptoRng`]: https://docs.rs/rand_core/latest/rand_core/trait.CryptoRng.html -[`Error`]: https://docs.rs/rand_core/latest/rand_core/struct.Error.html - -[`rngs`]: https://docs.rs/rand/latest/rand/rngs/ -[`distributions`]: https://docs.rs/rand/latest/rand/distributions/ -[`seq`]: https://docs.rs/rand/latest/rand/seq/ -[`Rng`]: https://docs.rs/rand/latest/rand/trait.Rng.html -[`random`]: https://docs.rs/rand/latest/rand/fn.random.html - -[`SmallRng`]: https://docs.rs/rand/latest/rand/rngs/struct.SmallRng.html diff --git a/src/crates.md b/src/crates.md index 72735e6..2f92c9b 100644 --- a/src/crates.md +++ b/src/crates.md @@ -1,61 +1,57 @@ -# Crates and features - -The Rand library consists of a family of crates. The [`rand`] crate provides the -main user-interface; where additional distributions are required, the -[`rand_distr`] or [`statrs`] crate may be used in addition. - -The library contains several building blocks: [`getrandom`] interfaces with the -platform-dependent random number source, [`rand_core`] defines the API that -generators must implement, and a number of crates like [`rand_chacha`] and -[`rand_xoshiro`] provide pseudo-random generators. - -```plain -getrandom ┐ - └ rand_core ┐ - ├ rand_chacha ┐ - ├ rand_hc ┤ - ├ rand_pcg ┤ - └─────────────┴ rand ┐ - ├ rand_distr - └ statrs -``` - -## Feature flags - -Rand crates allow some configuration via feature flags. Check the READMEs of -individual crates for details. - -No-std support is available across most Rand crates by disabling default -features: `rand = { version = "0.7", default-features = false }`. -This is affected by the following flags: - -- `std` opts-in to functionality dependent on the `std` lib -- `alloc` (implied by `std`) enables functionality requiring an allocator - (when using this feature in `no_std`, Rand requires Rustc version 1.36 or greater) - -Some Rand crates can be built with support for the following third-party crates: - -- `log` enables a few log messages via [`log`] -- `serde1` enables serialization via [`serde`], version 1.0 - -Note that cryptographic RNGs *do not* support serialisation since this could be -a security risk. If you need state-restore functionality on a cryptographic RNG, -the ChaCha generator supports [getting and setting the stream position](https://docs.rs/rand_chacha/latest/rand_chacha/struct.ChaCha20Rng.html#method.get_word_pos), -which, together with the seed, can be used to reconstruct the generator's state. - -## WASM support - -Almost all Rand crates support WASM out of the box. However, when using the -`wasm32-unknown-unknown` target, which doesn't make any assumptions about its -operating environment by default, the `getrandom` crate may require enabling -features for seeding entropy via the platform-provided APIs. -Consequently, if you are using `rand` (or another Rand project crate) -depending on `getrandom`, you may have to explicitly [enable `getrandom` -features](https://github.com/rust-random/getrandom#features) for seeding to -work. Alternatively, in case you are developing for a sandboxed or unknown -WASM platform that can't depend on environment provided APIs, you might want -to disable the `rand` crate's `getrandom` feature and seed the generator -manually. +# The crate family + +
statrs
+getrandom ┐                                ├ rand_distr
+          └ rand_core ┬─────────────┬ rand ┘
+                      ├ rand_chacha ┘
+                      ├ rand_pcg
+                      └ [other RNG crates]
+
+ +## Interfaces + +[`rand_core`] defines [`RngCore`] and other core traits, as well as several helpers for implementing RNGs. + +The [`getrandom`] crate provides a low-level API around platform-specific +random-number sources. + +## Pseudo-random generators + +The following crates implement pseudo-random number generators +(see [Our RNGs](guide-rngs.md)): + +- [`rand_chacha`] provides generators using the ChaCha cipher +- [`rand_hc`] implements a generator using the HC-128 cipher +- [`rand_isaac`] implements the ISAAC generators +- [`rand_pcg`] implements a small selection of PCG generators +- [`rand_xoshiro`] implements the SplitMix and Xoshiro generators +- [`rand_xorshift`] implements the basic Xorshift generator + +Exceptionally, [`SmallRng`] is implemented directly in [`rand`]. + +## rand (main crate) + +The [`rand`] crate is designed for easy usage of common random-number +functionality. This has several aspects: + +- the [`rngs`] module provides a few convenient generators +- the [`distributions`] module concerns sampling of random values +- the [`seq`] module concerns sampling from and shuffling sequences +- the [`Rng`] trait provides a few convenience methods for generating + random values +- the [`random`] function provides convenient generation in a single call + +## Distributions + +The [`rand`] crate only implements sampling from the most common random +number distributions: uniform and weighted sampling. For everything else, + +- [`rand_distr`] provides fast sampling from a variety of other distributions, + including Normal (Gauss), Binomial, Poisson, UnitCircle, and many more +- [`statrs`] is a port of the C# Math.NET library, implementing many of the + same distributions (plus/minus a few), along with PDF and CDF functions, + the *error*, *beta*, *gamma* and *logistic* special functions, plus a few + utilities. (For clarity, [`statrs`] is not part of the Rand library.) [`rand_core`]: https://docs.rs/rand_core/ @@ -64,6 +60,20 @@ manually. [`statrs`]: https://docs.rs/statrs/ [`getrandom`]: https://docs.rs/getrandom/ [`rand_chacha`]: https://docs.rs/rand_chacha/ +[`rand_pcg`]: https://docs.rs/rand_pcg/ [`rand_xoshiro`]: https://docs.rs/rand_xoshiro/ [`log`]: https://docs.rs/log/ [`serde`]: https://serde.rs/ +[`rand_hc`]: https://docs.rs/rand_hc/ +[`rand_isaac`]: https://docs.rs/rand_isaac/ +[`rand_xorshift`]: https://docs.rs/rand_xorshift/ + +[`RngCore`]: https://docs.rs/rand_core/latest/rand_core/trait.RngCore.html + +[`rngs`]: https://docs.rs/rand/latest/rand/rngs/ +[`distributions`]: https://docs.rs/rand/latest/rand/distributions/ +[`seq`]: https://docs.rs/rand/latest/rand/seq/ +[`Rng`]: https://docs.rs/rand/latest/rand/trait.Rng.html +[`random`]: https://docs.rs/rand/latest/rand/fn.random.html + +[`SmallRng`]: https://docs.rs/rand/latest/rand/rngs/struct.SmallRng.html diff --git a/src/guide-cargo.md b/src/guide-cargo.md deleted file mode 100644 index 70aeec9..0000000 --- a/src/guide-cargo.md +++ /dev/null @@ -1,39 +0,0 @@ -# Cargo and features - -The latest version of rand is available here: - -On the same page, and also from the repository's README, you can see documentation -of the [Crate Features](https://github.com/rust-random/rand#crate-features). -In particular, you may want to use the `small_rng` feature to enable the `SmallRng` generator. - -To add this dependency on Rand from the console, type: -```sh -cargo add rand --features small_rng -``` - -Or, add this to your `Cargo.toml`, under `[dependencies]`: -```toml -rand = { version = "0.8.5", features = ["small_rng"] } -``` - -Note: using `version = "0.8.5"` matches version `0.8.5`, `0.8.6`, etc., but not `0.9`. -Using instead `version = "0.8"` will match any `0.8.x` version. In both cases, -Cargo will normally install the latest matching version when the dependency is -first added. Dependencies may be updated later via `cargo update`, and in some -cases running `cargo update` can solve dependency problems. - -For more on Cargo, see [The Cargo Book](https://doc.rust-lang.org/cargo/). - -## Other crates - -As noted on the [Crates](crates.md) page, the Rand library consists of a family of crates. -To run the examples in this guide, ensure you have the following dependencies -in your `Cargo.toml`: -```toml -[dependencies] -rand = { version = "0.8.5", features = ["small_rng"] } -rand_chacha = "0.3.1" -rand_distr = "0.4.3" -rand_pcg = "0.3.1" -rand_seeder = "0.2.3" -``` diff --git a/src/guide-gen.md b/src/guide-gen.md index b75a618..518d0ec 100644 --- a/src/guide-gen.md +++ b/src/guide-gen.md @@ -48,7 +48,7 @@ number generators are deterministic and can be defined by just: The fact that these are deterministic can sometimes be very useful: it allows a simulation, randomised art work or game to be repeated exactly, producing a result which is a function of the seed. For more on this see the -[portability](portability.md) chapter (note that determinism alone isn't +[reproducibility](crate-reprod.md) chapter (note that determinism alone isn't enough to guarantee reproducibility). The other big attraction of PRNGs is their speed: some of these algorithms diff --git a/src/guide-parallel.md b/src/guide-parallel.md index 2b6e98c..31e3531 100644 --- a/src/guide-parallel.md +++ b/src/guide-parallel.md @@ -58,7 +58,7 @@ period). ## Practice: non-deterministic multi-threaded -We use [Rayon]'s parallel iterators, using [`map_init`] to initialize an RNG in +We use Rayon's [parallel iterators](https://docs.rs/rayon/latest/rayon/iter/index.html), using [`map_init`] to initialize an RNG in each worker thread. Note: this RNG may be re-used across multiple work units, which may be split between worker threads in non-deterministic fashion. @@ -142,3 +142,7 @@ fn main() { ); } ``` + +[`thread_rng`]: https://docs.rs/rand/latest/rand/fn.thread_rng.html +[`map_init`]: https://docs.rs/rayon/latest/rayon/iter/trait.ParallelIterator.html#method.map_init +[`ChaCha8Rng::set_stream`]: https://docs.rs/rand_chacha/latest/rand_chacha/struct.ChaCha8Rng.html#method.set_stream diff --git a/src/guide-rngs.md b/src/guide-rngs.md index db5e507..4d80a1b 100644 --- a/src/guide-rngs.md +++ b/src/guide-rngs.md @@ -55,8 +55,8 @@ RNGs do better with byte sequence output). Quality ratings are based on theory and observable defects, roughly as follows: - ★☆☆☆☆ = suitable for simple applications but with significant flaws -- ★★☆☆☆ = good performance in most tests, some issues -- ★★★☆☆ = good performance and theory, no major issues +- ★★☆☆☆ = no major issues in qualitative testing +- ★★★☆☆ = good theory, no major issues in qualitative testing - ★★★★★ = cryptographic quality ## Cryptographically secure pseudo-random number generators (CSPRNGs) @@ -260,16 +260,25 @@ 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 +### Not a cryptography 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 +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]. +The Rand crates attempt to provide unpredictable data sources, with limitations. +First, the software is provided "as is", without any form of guarantee. +Second, it is generally assumed that program memory is private; if there are +concerns in this regard it may be preferred to use an external generator such +as [`getrandom`] instead. Note that even privacy of freed memory is important, +and that while we may integrate some mitigations such as [zeroize] in the +future, such measures are incomplete. Note that Rand does not protect against +process forks (past versions of Rand up to 0.8.x have a limited mitigation but +not full protection). Finally, note that there are many possible ways that the +security of unpredictability could be broken, from complex hardware bugs like +Spectre to stupid mistakes like printing generator state in log messages. ## Extra features @@ -327,3 +336,4 @@ by P. Hellekalek. [ECRYPT]: http://www.ecrypt.eu.org/ [`getrandom`]: https://docs.rs/getrandom/ [`SeedableRng::from_entropy`]: https://docs.rs/rand/latest/rand/trait.SeedableRng.html#method.from_entropy +[zeroize]: https://crates.io/crates/zeroize diff --git a/src/guide-start.md b/src/guide-start.md index 1da65f1..19c4b9d 100644 --- a/src/guide-start.md +++ b/src/guide-start.md @@ -1,109 +1,53 @@ -# Getting Started +# Getting started -Below we list a short example. For more, please refer to the [API documentation] -or the [guide]. +If you haven't already, [install Rust](https://www.rust-lang.org/learn/get-started). -Lets kick things off with an example ([playground link](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=7792ed032694bc558ca229be71a7783a)): +Next, lets make a new crate and add rand as a dependency: +```sh +cargo new randomly +cd randomly +cargo add rand --features small_rng +``` -```rust,editable -# extern crate rand; -// import commonly used items from the prelude: +Now, paste the following into `src/main.rs`: +```rust use rand::prelude::*; fn main() { - // We can use random() immediately. It can produce values of many common types: - let x: u8 = random(); - println!("{}", x); + let mut rng = rand::thread_rng(); - if random() { // generates a boolean - println!("Heads!"); - } + println!("Random die roll: {}", rng.gen_range(1..=6)); + println!("Random UUID: 0x{:X}", rng.gen::()); - // If we want to be a bit more explicit (and a little more efficient) we can - // make a handle to the thread-local generator: - let mut rng = thread_rng(); - if rng.gen() { // random bool - let x: f64 = rng.gen(); // random number in range [0, 1) - let y = rng.gen_range(-10.0..10.0); - println!("x is: {}", x); - println!("y is: {}", y); + if rng.gen() { + println!("You got lucky!"); } - - println!("Dice roll: {}", rng.gen_range(1..=6)); - println!("Number from 0 to 9: {}", rng.gen_range(0..10)); - - // Sometimes it's useful to use distributions directly: - let distr = rand::distributions::Uniform::new_inclusive(1, 100); - let mut nums = [0i32; 3]; - for x in &mut nums { - *x = rng.sample(distr); - } - println!("Some numbers: {:?}", nums); - - // We can also interact with iterators and slices: - let arrows_iter = "➡⬈⬆⬉⬅⬋⬇⬊".chars(); - println!("Lets go in this direction: {}", arrows_iter.choose(&mut rng).unwrap()); - let mut nums = [1, 2, 3, 4, 5]; - nums.shuffle(&mut rng); - println!("I shuffled my {:?}", nums); } ``` -The first thing you may have noticed is that we imported everything from the -[prelude]. This is the lazy way to `use` rand, and like the -[standard library's prelude](https://doc.rust-lang.org/std/prelude/), -only imports the most common items. If you don't wish to use the prelude, -remember to import the [`Rng`] trait! - -The Rand library automatically initialises a secure, thread-local generator -on demand. This can be accessed via the [`thread_rng`] and [`random`] functions. -For more on this topic, see [Random generators](guide-gen.md). - -While the [`random`] function can only sample values in a [`Standard`] -(type-dependent) manner, [`thread_rng`] gives you a handle to a generator. -All generators implement the [`Rng`] trait, which provides the [`gen`], -[`gen_range`] and [`sample`] methods used above. - -Rand provides functionality on iterators and slices via two more traits, -[`IteratorRandom`] and [`SliceRandom`]. - -## Fixed seed RNGs - -You may have noticed the use of `thread_rng()` above and wondered how to -specify a fixed seed. To do so, you need to specify an RNG then use a method -like [`seed_from_u64`] or [`from_seed`]. - -Note that [`seed_from_u64`] is **not suitable for cryptographic uses** since a -single `u64` cannot provide sufficient entropy to securely seed an RNG. -All cryptographic RNGs accept a more appropriate seed via [`from_seed`]. - -We use `ChaCha8Rng` below because it is fast and portable with good quality. -See the [RNGs] section for more RNGs, but avoid `SmallRng` and `StdRng` if you -care about reproducible results. - -```rust,editable -# extern crate rand; -# extern crate rand_chacha; -use rand::{Rng, SeedableRng}; - -fn main() { - let mut rng = rand_chacha::ChaCha8Rng::seed_from_u64(10); - println!("Random f32: {}", rng.gen::()); -} +Now lets go! +```sh +$ cargo run + Compiling [..] + Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.99s + Running `target/debug/randomly` +Random die roll: 4 +Random UUID: 0xEC3936A465339F8295EE11AB853CCDBF +You got lucky! ``` -[API documentation]: https://docs.rs/rand/ -[guide]: guide.md -[RNGs]: guide-rngs.md -[prelude]: https://docs.rs/rand/latest/rand/prelude/ -[`Rng`]: https://docs.rs/rand/latest/rand/trait.Rng.html -[`gen`]: https://docs.rs/rand/latest/rand/trait.Rng.html#method.gen -[`gen_range`]: https://docs.rs/rand/latest/rand/trait.Rng.html#method.gen_range -[`sample`]: https://docs.rs/rand/latest/rand/trait.Rng.html#method.sample -[`thread_rng`]: https://docs.rs/rand/latest/rand/fn.thread_rng.html -[`random`]: https://docs.rs/rand/latest/rand/fn.random.html -[`Standard`]: https://docs.rs/rand/latest/rand/distributions/struct.Standard.html -[`IteratorRandom`]: https://docs.rs/rand/latest/rand/seq/trait.IteratorRandom.html -[`SliceRandom`]: https://docs.rs/rand/latest/rand/seq/trait.SliceRandom.html -[`seed_from_u64`]: https://docs.rs/rand/latest/rand/trait.SeedableRng.html#method.seed_from_u64 -[`from_seed`]: https://docs.rs/rand/latest/rand/trait.SeedableRng.html#tymethod.from_seed +## Other crates + +Some other [crates](crates.md) are used by this guide. When needed, you can either edit the `[dependencies]` section of your `Cargo.toml` or use `cargo add`: +```sh +$ cargo add rand_distr + Updating crates.io index + Adding rand_distr v0.4.3 to dependencies + Features: + + alloc + + std + - serde + - serde1 + - std_math + Updating crates.io index +``` diff --git a/src/guide.md b/src/guide.md index f1e4f25..6de3c41 100644 --- a/src/guide.md +++ b/src/guide.md @@ -2,6 +2,7 @@ This section attempts to explain some of the concepts used in this library. +1. [Getting started with a new crate](guide-cargo.md) 1. [What is random data and what is randomness anyway?](guide-data.md) 1. [What kind of random generators are there?](guide-gen.md) 1. [What random number generators does Rand provide?](guide-rngs.md) diff --git a/src/intro.md b/src/intro.md index cf90eb1..3a92782 100644 --- a/src/intro.md +++ b/src/intro.md @@ -4,11 +4,9 @@ This is the extended documentation for Rust's **Rand**om number library. This book contains: -1. [Getting Started](guide-start.md) -1. An overview of [crates and functionality](crates.md) +1. [Quick start](quick-start.md) +1. An overview of [crates, features and portability](crates.md) 3. The [Users' Guide](guide.md) -4. Notes on [Portability and Reproducibility](portability.md). - (Read this if you want reproducibility across builds.) 5. [Updating guides](update.md) 6. [Contributor's guide](contributing.md) diff --git a/src/portability.html b/src/portability.html new file mode 100644 index 0000000..f231436 --- /dev/null +++ b/src/portability.html @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/quick-start.md b/src/quick-start.md new file mode 100644 index 0000000..d6f004a --- /dev/null +++ b/src/quick-start.md @@ -0,0 +1,109 @@ +# Quick start + +Below we list a short example. For more, please refer to the [API documentation] +or the [guide]. + +Lets kick things off with an example ([playground link](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=7792ed032694bc558ca229be71a7783a)): + +```rust,editable +# extern crate rand; +// import commonly used items from the prelude: +use rand::prelude::*; + +fn main() { + // We can use random() immediately. It can produce values of many common types: + let x: u8 = random(); + println!("{}", x); + + if random() { // generates a boolean + println!("Heads!"); + } + + // If we want to be a bit more explicit (and a little more efficient) we can + // make a handle to the thread-local generator: + let mut rng = thread_rng(); + if rng.gen() { // random bool + let x: f64 = rng.gen(); // random number in range [0, 1) + let y = rng.gen_range(-10.0..10.0); + println!("x is: {}", x); + println!("y is: {}", y); + } + + println!("Dice roll: {}", rng.gen_range(1..=6)); + println!("Number from 0 to 9: {}", rng.gen_range(0..10)); + + // Sometimes it's useful to use distributions directly: + let distr = rand::distributions::Uniform::new_inclusive(1, 100); + let mut nums = [0i32; 3]; + for x in &mut nums { + *x = rng.sample(distr); + } + println!("Some numbers: {:?}", nums); + + // We can also interact with iterators and slices: + let arrows_iter = "➡⬈⬆⬉⬅⬋⬇⬊".chars(); + println!("Lets go in this direction: {}", arrows_iter.choose(&mut rng).unwrap()); + let mut nums = [1, 2, 3, 4, 5]; + nums.shuffle(&mut rng); + println!("I shuffled my {:?}", nums); +} +``` + +The first thing you may have noticed is that we imported everything from the +[prelude]. This is the lazy way to `use` rand, and like the +[standard library's prelude](https://doc.rust-lang.org/std/prelude/), +only imports the most common items. If you don't wish to use the prelude, +remember to import the [`Rng`] trait! + +The Rand library automatically initialises a secure, thread-local generator +on demand. This can be accessed via the [`thread_rng`] and [`random`] functions. +For more on this topic, see [Random generators](guide-gen.md). + +While the [`random`] function can only sample values in a [`Standard`] +(type-dependent) manner, [`thread_rng`] gives you a handle to a generator. +All generators implement the [`Rng`] trait, which provides the [`gen`], +[`gen_range`] and [`sample`] methods used above. + +Rand provides functionality on iterators and slices via two more traits, +[`IteratorRandom`] and [`SliceRandom`]. + +## Fixed seed RNGs + +You may have noticed the use of `thread_rng()` above and wondered how to +specify a fixed seed. To do so, you need to specify an RNG then use a method +like [`seed_from_u64`] or [`from_seed`]. + +Note that [`seed_from_u64`] is **not suitable for cryptographic uses** since a +single `u64` cannot provide sufficient entropy to securely seed an RNG. +All cryptographic RNGs accept a more appropriate seed via [`from_seed`]. + +We use `ChaCha8Rng` below because it is fast and portable with good quality. +See the [RNGs] section for more RNGs, but avoid `SmallRng` and `StdRng` if you +care about reproducible results. + +```rust,editable +# extern crate rand; +# extern crate rand_chacha; +use rand::{Rng, SeedableRng}; + +fn main() { + let mut rng = rand_chacha::ChaCha8Rng::seed_from_u64(10); + println!("Random f32: {}", rng.gen::()); +} +``` + +[API documentation]: https://docs.rs/rand/ +[guide]: guide.md +[RNGs]: guide-rngs.md +[prelude]: https://docs.rs/rand/latest/rand/prelude/ +[`Rng`]: https://docs.rs/rand/latest/rand/trait.Rng.html +[`gen`]: https://docs.rs/rand/latest/rand/trait.Rng.html#method.gen +[`gen_range`]: https://docs.rs/rand/latest/rand/trait.Rng.html#method.gen_range +[`sample`]: https://docs.rs/rand/latest/rand/trait.Rng.html#method.sample +[`thread_rng`]: https://docs.rs/rand/latest/rand/fn.thread_rng.html +[`random`]: https://docs.rs/rand/latest/rand/fn.random.html +[`Standard`]: https://docs.rs/rand/latest/rand/distributions/struct.Standard.html +[`IteratorRandom`]: https://docs.rs/rand/latest/rand/seq/trait.IteratorRandom.html +[`SliceRandom`]: https://docs.rs/rand/latest/rand/seq/trait.SliceRandom.html +[`seed_from_u64`]: https://docs.rs/rand/latest/rand/trait.SeedableRng.html#method.seed_from_u64 +[`from_seed`]: https://docs.rs/rand/latest/rand/trait.SeedableRng.html#tymethod.from_seed diff --git a/src/update-0.8.md b/src/update-0.8.md index 52d6c92..59e1a40 100644 --- a/src/update-0.8.md +++ b/src/update-0.8.md @@ -209,7 +209,7 @@ directly. ## Tests Value-stability tests were added for all distributions ([rand#786]), helping -enforce our rules regarding value-breaking changes (see [Portability] section). +enforce our rules regarding value-breaking changes (see [Reproducibility] section). [`Fill`]: https://docs.rs/rand/latest/rand/trait.Fill.html @@ -245,5 +245,5 @@ enforce our rules regarding value-breaking changes (see [Portability] section). [`LogNormal`]: https://docs.rs/rand_distr/latest/rand_distr/struct.LogNormal.html [rand#932]: https://github.com/rust-random/rand/issues/932 [rand#786]: https://github.com/rust-random/rand/issues/786 -[Portability]: ./portability.html +[Reproducibility]: ./crate-reprod.html [Serde]: https://serde.rs/