Expand description
§mod-rand
Tiered random number generation for Rust. Zero dependencies. Pick the tier appropriate to your threat model.
§Tiers
Each tier is also available under a plain name. The plain names are the same modules, so mixing them is fine.
secure(same astier3): OS-backed cryptographic random. The only choice for tokens, passwords, keys, session IDs, and temp names in shared directories. Calls platform syscalls directly.unique(same astier2): process-unique values derived from PID + time + counter. For request IDs, log correlation, and names in private directories. Fast enough for high-frequency use. Predictable, so never a token or a password.seeded(same astier1): deterministic seedable PRNG (xoshiro256**). For simulation, fixture data, non-security shuffling. Always available, works inno_std. Reproducible from its seed, so never a token or a password.
§Quick example
Raw draws:
use mod_rand::tier1::Xoshiro256;
let mut rng = Xoshiro256::seed_from_u64(42);
let n: u64 = rng.next_u64();Bounded ranges — every tier exposes a parallel gen_range_* /
range_* / random_range_* family that uses Lemire’s “Nearly
Divisionless” rejection sampling under the hood, so output is
uniformly distributed with no modulo bias:
use mod_rand::tier1::Xoshiro256;
let mut rng = Xoshiro256::seed_from_u64(42);
// Half-open: never returns 100.
let pct: u32 = rng.gen_range_u32(0..100);
// Inclusive: classic six-sided die.
let d6: u32 = rng.gen_range_inclusive_u32(1..=6);The same .. (half-open) vs ..= (inclusive) convention applies
on Tier 2 (free functions) and Tier 3 (free functions returning
io::Result):
use mod_rand::{tier2, tier3};
let id = tier2::range_inclusive_u32(1..=1_000);
let key = tier3::random_range_inclusive_u64(0..=u64::MAX)?;§Choosing a tier
| Use case | Module |
|---|---|
| Test fixtures, simulation | seeded (tier 1) |
| Request IDs, names in a private directory | unique (tier 2) |
| Tokens, passwords, session IDs, keys, salts | secure (tier 3) |
Temp file or directory names in /tmp | secure (tier 3) |
If an attacker could gain anything by predicting the value, use
secure.
let token = mod_rand::secure::random_alphanumeric(32)?;
let key = mod_rand::secure::random_bytes(32)?;§Status
1.x is API-stable under SemVer: full xoshiro256** with
splitmix64 seeding (tier 1), Stafford-mix-13 over (PID + nanos +
atomic counter + per-process salt) (tier 2), and direct platform
syscalls for tier 3 (getrandom(2) / BCryptGenRandom /
getentropy(3)). All bounded-range methods use Lemire’s
“Nearly Divisionless” rejection sampling, verified for uniformity
by 1,000,000-draw chi-squared tests at the integration level.
See the CHANGELOG
for release history.
Modules§
- charsets
- Charset constants
- secure
tier3 - OS-backed cryptographic random: the same module as
tier3. - seeded
- Deterministic seedable PRNG: the same module as
tier1. - tier1
- Tier 1 — Fast deterministic PRNG
- tier2
tier2 - Tier 2 — Process-unique seeds
- tier3
tier3 - Tier 3 — OS-backed cryptographic random
- unique
tier2 - Process-unique values: the same module as
tier2.