A collection of efficient pseudo-random number generators (PRNGs) implemented in pure Rust. This crate provides a wide variety of algorithms, ranging from standard Mersenne Twister to modern high-performance generators like Xoshiro and Philox.
Add this to your Cargo.toml:
[dependencies]
urng = "0.4.9"Generators are divided into two categories: standard generators and AVX-accelerated SIMD generators.
Standard generators implement either the Rng32 or Rng64 trait (or return fixed-size arrays for counter-based variants).
AVX generators expose a bulk-generation API and are listed separately.
| Struct | Algorithm | Period / State |
|---|---|---|
Mt19937 |
Mersenne Twister | |
Sfmt607 |
SFMT | |
Sfmt1279 |
SFMT | |
Sfmt2281 |
SFMT | |
Sfmt4253 |
SFMT | |
Sfmt11213 |
SFMT | |
Sfmt19937 |
SFMT | |
Sfmt44497 |
SFMT | |
Sfmt86243 |
SFMT | |
Sfmt132049 |
SFMT | |
Sfmt216091 |
SFMT | |
Sfc32 |
SFC32 | |
Sfc32x4 |
SFC32 x4 | |
Pcg32 |
PCG-XSH-RR | |
Philox32x4 |
Philox 4x32 | - |
SplitMix32 |
SplitMix32 | |
Xorwow |
XORWOW | |
Xorshift32 |
Xorshift | |
Xorshift128 |
Xorshift128 | |
Xoshiro128Pp |
xoshiro128++ | |
Xoshiro128Ss |
xoshiro128** | |
Xoroshiro64Ss |
xoroshiro64** | |
Lcg32 |
LCG | |
Threefry32x4 |
Threefry 4x32 | - |
Threefry32x2 |
Threefry 2x32 | - |
Squares32 |
Squares | - |
Jsf32 |
JSF32 | - |
| Struct | Algorithm | Period / State |
|---|---|---|
Xoshiro256Pp |
xoshiro256++ | |
Xoshiro256Ss |
xoshiro256** | |
SplitMix64 |
SplitMix64 | |
Sfc64 |
SFC64 |
|
Mt1993764 |
Mersenne Twister 64 | |
Sfmt1993764 |
SFMT 64 | |
Philox64 |
Philox 2x64 | - |
Xorshift64 |
Xorshift64 | |
Xoroshiro128Pp |
xoroshiro128++ | |
Xoroshiro128Ss |
xoroshiro128** | |
TwistedGFSR |
TGFSR |
|
Cet64 |
CET | |
Cet256 |
CET | |
Lcg64 |
LCG | |
Threefish256 |
Threefish-256 | - |
Biski64 |
Biski64 |
These generators expose a bulk-generation API and require AVX support at runtime.
| Struct | Algorithm | Output |
|---|---|---|
Sfc32x8 |
SFC32 x8 | 8×u32 |
Jsf32x8 |
JSF32 x8 | 8×u32 |
Xoroshiro64Ssx8 |
xoroshiro64** x8 | 8×u32 |
| Struct | Algorithm | Output |
|---|---|---|
Pcg32x8 |
PCG-XSH-RR x8 | 8×u32 |
Philox32x4x4 |
Philox 4x32 x4 | 16×u32 |
SplitMix32x16 |
SplitMix32 x16 | 16×u32 |
Squares32x8 |
Squares x8 | 8×u32 |
Xoshiro128Ppx16 |
xoshiro128++ x16 | 16×u32 |
Xoshiro128Ssx16 |
xoshiro128** x16 | 16×u32 |
Jsf32x16 |
JSF32 x16 | 16×u32 |
Sfc32x16 |
SFC32 x16 | 16×u32 |
Xoroshiro64Ssx16 |
xoroshiro64** x16 | 16×u32 |
Xoshiro256Ssx2 |
xoshiro256** x2 | 2×u64 |
Sfc64x8 |
SFC64 x8 | 8×u64 |
Cet64x8 |
CET64 x8 | 8×u64 |
Cet256x2 |
CET256 x2 | 2×u64 |
Biski64x8 |
Biski64 x8 | 8×u64 |
Requires the
samplerfeature.
Weighted random index selection. Two implementations are provided for each bit-width, both implementing the Sampler32 / Sampler64 trait (urng::sampler).
| Struct | Module | Algorithm | Build | Sample |
|---|---|---|---|---|
Bst32 |
urng::sampler32 |
Cumulative BST | O(n) | O(log n) |
Alias32 |
urng::sampler32 |
Walker's Alias | O(n) | O(1) |
Bst64 |
urng::sampler64 |
Cumulative BST | O(n) | O(log n) |
Alias64 |
urng::sampler64 |
Walker's Alias | O(n) | O(1) |
Requires the
seedgenfeature.
Hardware-noise-assisted seed generation. Wraps an existing Rng32/Rng64 and mixes in hardware noise (RDSEED/RDRAND on x86/x86_64, timestamp fallback elsewhere) via a Murmur3-style hash.
| Struct | Module | Input RNG | Output |
|---|---|---|---|
SeedGen32 |
urng::seedgen |
Rng32 |
(u32, u32) pair |
SeedGen64 |
urng::seedgen |
Rng64 |
(u64, u64) pair |
next_seed_pair() returns (raw, processed) — the raw hardware value and the mixed seed.
Most generators expose the same basic workflow: create an instance with new, then use nextu, nextf, randi, randf, or choice depending on the output type you need. SIMD and counter-based generators return fixed-size arrays instead of single values.
use urng::prelude::*;
fn main() {
// 1. Initialize with a seed
let mut rng = Xoshiro256Pp::new(12345);
// 2. Generate random numbers
let val_u64 = rng.nextu();
println!("u64: {}", val_u64);
let val_f64 = rng.nextf(); // [0.0, 1.0)
println!("f64: {}", val_f64);
// 3. Generate within a range
let val_range = rng.randi(1, 100);
println!("Integer (1-100): {}", val_range);
// 4. Seeding with SplitMix64 (common pattern)
// If you need to seed a large state generator from a single u64
let mut sm = SplitMix64::new(9999);
let seed_val = sm.nextu();
let mut rng2 = Xoshiro256Pp::new(seed_val);
}This crate exports a C-compatible ABI generic interface. Each generator has corresponding:
_new_free_next_uXXs(bulk generation)_next_fXXs(bulk generation)_rand_iXXs(bulk generation)_rand_fXXs(bulk generation)
Example for Mt19937:
void* mt19937_new(uint32_t seed, size_t warm);
void mt19937_next_u32s(void* ptr, uint32_t* out, size_t count);
void mt19937_rand_f32s(void* ptr, float* out, size_t count, float min, float max);
void mt19937_free(void* ptr);