CSPRNG-first random utilities for Go. Small, composable generators with bias-free numeric helpers, strings/tokens, distributions, UUIDs, and sampling utilities.
go get github.com/aatuh/randutil/v2Requires Go 1.24+.
package main
import (
"fmt"
"github.com/aatuh/randutil/v2"
)
func main() {
r := randutil.Default()
b := r.Numeric.MustBytes(16)
tok := r.String.MustTokenURLSafe(24)
u4 := r.UUID.MustV4()
when := r.Time.MustDatetime()
fmt.Println(len(b), tok, u4, when)
}Use a deterministic source and pass it into core.New, then share the RNG
across generators:
package main
import (
"fmt"
"github.com/aatuh/randutil/v2/adapters"
"github.com/aatuh/randutil/v2/core"
"github.com/aatuh/randutil/v2/randstring"
)
func main() {
rng := core.New(adapters.DeterministicSource([]byte("seed")))
gen := randstring.New(rng)
s, _ := gen.String(12)
fmt.Println(s)
}For exact byte control in tests, pass a custom io.Reader into core.New.
- Default entropy is
crypto/rand.Reader. - No process-wide mutable state; each generator binds its own source/RNG.
- Unbiased sampling (rejection sampling for ranges/charsets).
- Token string helpers return immutable strings; use
Token*Byteswhen secrets must be wipeable. - Deterministic sources are for testing and benchmarks only.
If your source or RNG is not thread-safe, wrap it with
adapters.LockedSource or adapters.LockedRNG.
URL-safe token:
s := randstring.MustTokenURLSafe(24) // ~32 chars, URL-safeRange and sampling:
n := numeric.MustIntRange(10, 20) // inclusive
arr := []int{1, 2, 3, 4, 5}
collection.MustShuffle(arr)
subset := collection.MustSample(arr, 2)UUIDs:
u4 := uuid.MustV4()
u7 := uuid.MustV7()Distributions:
x := dist.MustNormal(0, 1)
k := dist.MustPoisson(12)Email:
mail := email.MustEmail(email.Options{TLD: "org"})Every MustX(...) has a non-panicking X(...) variant that returns
(T, error) for server/CLI contexts.
The example_test.go file contains executable examples that appear in
godoc and are run by go test to prevent documentation drift.