Universal RNG
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.
Supported Generators
Generators are divided into standard generators, portable wide generators, and AVX-accelerated SIMD generators.
Standard generators implement either the Rng32 or Rng64 trait (or return fixed-size arrays for counter-based variants).
Portable wide generators require the wide feature and expose safe fixed-array bulk APIs.
AVX generators expose a bulk-generation API and are listed separately; they require the simd feature.
32-bit Generators (urng::rng32)
| Struct | Algorithm | Period / State |
|---|---|---|
Mt19937 |
Mersenne Twister | $2^{19937}-1$ |
Sfmt607 |
SFMT | $2^{607}-1$ |
Sfmt1279 |
SFMT | $2^{1279}-1$ |
Sfmt2281 |
SFMT | $2^{2281}-1$ |
Sfmt4253 |
SFMT | $2^{4253}-1$ |
Sfmt11213 |
SFMT | $2^{11213}-1$ |
Sfmt19937 |
SFMT | $2^{19937}-1$ |
Sfmt44497 |
SFMT | $2^{44497}-1$ |
Sfmt86243 |
SFMT | $2^{86243}-1$ |
Sfmt132049 |
SFMT | $2^{132049}-1$ |
Sfmt216091 |
SFMT | $2^{216091}-1$ |
Sfc32 |
SFC32 | $2^{127}-1$ |
Sfc32x4 |
SFC32 x4 | $2^{127}-1$ |
Pcg32 |
PCG-XSH-RR | $2^{64}$ |
Philox32x4 |
Philox 4x32 | - |
SplitMix32 |
SplitMix32 | $2^{32}$ |
Xorwow |
XORWOW | $2{192}-2{32}$ |
Xorshift32 |
Xorshift | $2^{32}-1$ |
Xorshift128 |
Xorshift128 | $2^{128}-1$ |
Xoshiro128Pp |
xoshiro128++ | $2^{128}-1$ |
Xoshiro128Ss |
xoshiro128** | $2^{128}-1$ |
Xoroshiro64Ss |
xoroshiro64** | $2^{64}-1$ |
Lcg32 |
LCG | $m$ |
Threefry32x4 |
Threefry 4x32 | - |
Threefry32x2 |
Threefry 2x32 | - |
Squares32 |
Squares | - |
Jsf32 |
JSF32 | - |
64-bit Generators (urng::rng64)
| Struct | Algorithm | Period / State |
|---|---|---|
Xoshiro256Pp |
xoshiro256++ | $2^{256}-1$ |
Xoshiro256Ss |
xoshiro256** | $2^{256}-1$ |
SplitMix64 |
SplitMix64 | $2^{64}$ |
Sfc64 |
SFC64 | $2^{256}$ approx |
Mt1993764 |
Mersenne Twister 64 | $2^{19937}-1$ |
Sfmt1993764 |
SFMT 64 | $2^{19937}-1$ |
Philox64 |
Philox 2x64 | - |
Xorshift64 |
Xorshift64 | $2^{64}-1$ |
Xoroshiro128Pp |
xoroshiro128++ | $2^{128}-1$ |
Xoroshiro128Ss |
xoroshiro128** | $2^{128}-1$ |
TwistedGFSR |
TGFSR | $2^{800}$ approx |
Cet64 |
CET | $2^{64}$ |
Cet256 |
CET | $2^{256}$ |
Lcg64 |
LCG | $m$ |
Threefish256 |
Threefish-256 | - |
Biski64 |
Biski64 | $2^{64}$ |
Portable Wide Generators (urng::wide)
Requires the
widefeature.
These generators use the portable wide crate and expose safe nextu, nextf, randi, and randf methods returning fixed-size arrays.
| Struct family | Algorithm | Output variants |
|---|---|---|
SplitMix32x* |
SplitMix32 | 4×/8×/16×u32 |
Jsf32x* |
JSF32 | 4×/8×/16×u32 |
Pcg32x* |
PCG-XSH-RR | 4×/8×/16×u32 |
Sfc32x* |
SFC32 | 4×/8×/16×u32 |
Xoroshiro64Ssx* |
xoroshiro64** | 4×/8×/16×u32 |
Xorshift32x* |
Xorshift32 | 4×/8×/16×u32 |
Xorshift128x* |
Xorshift128 | 4×/8×/16×u32 |
Xorwowx* |
XORWOW | 4×/8×/16×u32 |
Xoshiro128Ppx* |
xoshiro128++ | 4×/8×/16×u32 |
Xoshiro128Ssx* |
xoshiro128** | 4×/8×/16×u32 |
Example:
use Xoshiro128Ppx16;
let mut rng = new;
let values: = rng.nextu;
let floats: = rng.nextf;
SIMD Generators (AVX)
These generators expose a bulk-generation API and require AVX support at runtime.
AVX2 (avx2)
| Struct | Algorithm | Output |
|---|---|---|
Sfc32x8 |
SFC32 x8 | 8×u32 |
Jsf32x8 |
JSF32 x8 | 8×u32 |
Xoroshiro64Ssx8 |
xoroshiro64** x8 | 8×u32 |
AVX-512 (avx512f)
| 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 |
Sampler
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) |
SeedGen
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.
Testing
Statistical validation of RNG quality is handled by the external cribler crate, a batteries-included randomness-test toolkit. cribler ships every engine (chi-squared, Monte Carlo π, serial correlation, runs, Kolmogorov–Smirnov, birthday spacing, a NIST SP 800-22 subset, and a paranoid battery aggregator) and offers zero-feature integration: any generator plugs in via a plain FnMut() -> f64 / FnMut() -> u64 sampler closure.
Enable the urng feature on cribler for pre-built typed convenience that works directly against urng's Rng32/Rng64 generators:
[]
= "0.12.0"
= { = "0.3", = ["urng"] }
The suites construct each named case from a seed, so no generator instance needs to be passed in:
use ChiSqSuite;
use *;
let results = new
.?
.?
.?
.?
.from_custom?
.run?;
for r in &results
from_urng32::<R>() / from_urng64::<R>() register a urng::Rng32 / urng::Rng64 R, built from the suite's seed. The rand feature provides from_rand::<R>() for rand_core::Rng types, and from_custom(source) accepts anything else via a WordSource adapter.
Usage Examples
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.
Scalar generators (both 32-bit and 64-bit; SIMD variants are not included) also implement Default, seeding themselves from a time-based, per-call mix so no explicit seed is required:
use *;
let mut rng = default;
let _ = rng.nextu;
The deprecated
Lcg32/Lcg64implementDefaultwith the fixed parametersnew(8, 13, 5, 24)instead, since an LCG has no single sensible auto-generated seed.
Basic Usage
use *;
C ABI
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* ;
void ;
void ;
void ;