4 releases
new 0.2.1 | Jan 10, 2025 |
---|---|
0.2.0 | Dec 27, 2024 |
0.1.1 | Nov 4, 2022 |
0.1.0 | Aug 4, 2020 |
#124 in Algorithms
640 downloads per month
Used in 3 crates
160KB
2.5K
SLoC
µrandom
Produce and consume randomness.
This crate provides utilities to generate random numbers, to convert them to useful types and distributions, and some randomness-related algorithms.
This library is a fork of the semi-official rand
crate and an attempt to provide a better experience.
Usage
Add this to your Cargo.toml
:
[dependencies]
urandom = "0.2"
Quick Start
To get you started quickly, the easiest and highest-level way to get a random value is to use urandom::new().next()
.
The Random
struct provides a useful API on all Rngs, while the distr
module provide further functionality on top of Rngs.
let mut rand = urandom::new();
// Generates a random boolean
if rand.coin_flip() {
// Try printing a random unicode code point (probably a bad idea)!
println!("char: {}", rand.next::<char>());
}
// Generates a float between 13.0 and 42.0
let y: f64 = rand.range(13.0..42.0);
// Shuffles the list of numbers
let mut numbers: Vec<i32> = (1..100).collect();
rand.shuffle(&mut numbers);
Features
-
std
(default): Enable features that require the standard library.Without this feature, the crate can be used in
no_std
environments with limited functionality. -
getrandom
(default): Use thegetrandom
crate to get random bytes from the operating system. This is the default source of randomness. -
serde
: Enable serialization and deserialization support for the random number generators and distributions.
Frequently Asked Questions
-
Why another random number generator crate?
I think the semi-official
rand
crate has some design issues that I can improve upon.The focus of this crate is on the ergonomics of the consumer side of randomness.
-
How does this crate improve on the
rand
crate?-
The
rand
crate overuses traits to provide its API to consumers. While traits are great they are not the easiest to work with, requiring figuring out which traits to import and on which types they are implemented.This crate uses inherent methods on the
Random
struct to provide a more ergonomic and consistent API. Looking for an RNG method? It's on theRandom
struct. -
The
rand
crate puts itsthread_rng
front and center as it's the easiest way to generate randomness (through explicit use orrandom
method).In my personal opinion thread local variables are not a good idea and should be avoided for the same reasons as global state.
This crate uses explicit state management and seeds new PRNGs directly from the system's
getrandom
. -
The
rand
crate has an inefficient implementation of generating unbiased uniform integers in a range.This crate uses a more efficient algorithm which avoids an expensive integer division. See the benchmarks against
rand
for details. -
The
rand
crate's code is spread over several different crates which makes it harder to understand and contribute to.This crate is a single crate with a single focus: providing a better experience for consumers of randomness.
-
-
Which features of the
rand
crate are good?The distribution trait and related types are fairly well designed and didn't need much change.
-
Which random number generators are implemented?
PRNG for non cryptographic use:
Xoshiro256
by Sebastiano Vigna and David Blackman.Cryptographically secure PRNG:
ChaCha12
by Daniel J. Bernstein.getrandom
as the source of system entropy. -
Can I implement my own random number generator?
Yes, you can but it is not recommended. The chosen PRNGs are fast, well known and have good statistical properties.
By not exposing consumers to the PRNG implementation details, the crate's API surface is kept small and simple.
-
The Rng traits are incompatible with
rand
, is this a problem?No. The traits are only necessary to implement new Rngs but by design it is not recommended to do this. Consumers of randomness should use the
Random
struct and its methods. -
Why are random floats generated in the half-open interval
[1.0, 2.0)
instead of[0.0, 1.0)
?Because it's very easy to generate a random float in that half open range (generate a random mantissa with a fixed exponent) and it avoids hard (design and implementation) questions.
Converting to float and dividing by the integer range leaves a bias in the low bits of the float's mantissa. The same issue arises when subtracting
1.0
from a random float in the[1.0, 2.0)
range (seeexamples/float_bias.rs
).The
Float01
distribution generates a true, unbiased random float in open interval(0.0, 1.0)
. -
Is it performant on 32-bit archs?
This crate is optimized for 64-bit archs with fast full 64-bit integer multiplication in mind. The same PRNGs are used on 32-bit archs to ensure compatibility and consistent behavior. This means the performance is not as good as on 64-bit archs.
License
Licensed under MIT License, see license.txt.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, shall be licensed as above, without any additional terms or conditions.
Dependencies
~91–415KB