Pseudo-random number and string primitives for non-security workloads, plus a crypto-strong subset for tokens and verification codes. Pure standard library.
The package exposes two distinct sources, picked by use case:
- Pseudo-random (the bulk of the API) delegates to the
math/rand/v2package-level functions, which use a concurrent-safe global source. Safe to call from many goroutines. Fast; NOT for security. - Cryptographically secure (
Crypto*) delegates tocrypto/rand. Slower; use for tokens, session IDs, 2FA seeds, and anything an attacker must not predict.
The earlier implementation held a shared *rand.Rand. That type is not safe for
concurrent use and panics (index out of range [-1]) under parallel load.
math/rand/v2 package-level functions are concurrency-safe and auto-seeded, so
Seed / SeedReset are retained as no-ops for backward compatibility.
Int() intnon-negative int.IntBetween(min, max int) intint in[min, max).Int31() int32,Int31Between(min, max int32) int3231-bit.Int63() int64,Int63Between(min, max int64) int6463-bit.Uint32() uint32,Uint64() uint64.Float32() float32,Float32Between(min, max float32) float32.Float64() float64,Float64Between(min, max float64) float64.NormFloat64() float64standard normal (mean 0, stddev 1).ExpFloat64() float64exponentially distributed (rate 1).Percent() float64in[0, 100.0].Perm(n int) []intpermutation of[0, n).PermBetween(min, max int) []intpermutation of[min, max).Shuffle(n int, swap func(i, j int))Fisher-Yates.Read(p []byte) (n int, err error)fillspfromcrypto/rand(kept under the random namespace; the non-securitymath/randsource has no package-levelReadin v2).
RandStringWithLetter(n int) string[a-zA-Z].RandStringWithLetterDigits(n int) string[0-9a-zA-Z].RandStringInCharset(n int, charset []rune) stringarbitrary runes (1-4 bytes each).RandStringWithKind(n int, kind int) []bytebitmask of digit/upper/lower.StringByRead(b []byte) stringbase64 ofcrypto/randbytes, lengthlen(b).NumericCode(n int) stringn-digit string, leading zeros allowed (SMS/email codes).RandUniCodeByUID(uid uint64, n int) stringdeterministic-looking code from a UID (n < 10); see the diffusion/confusion comment in source.RandUniCodeByUIDWithSalt(uid uint64, n int, salt uint64) stringsame, with caller salt.
RandIn[T any](slice []T) (T, error)one element; empty slice returnsErrEmptySlice(no panic).MustRandIn[T any](slice []T) Tone element; panics on empty (for callers that have already validated non-emptiness).RandNIn[T any](n int, slice []T) []Tn distinct elements.
CryptoInt(max int64) (*big.Int, error)uniform in[0, max).CryptoPrime(bits int) (*big.Int, error)probable prime of bit lengthbits.CryptoRead(b []byte) (n int, err error)fillsb.CryptoReadString(b []byte) stringbase64 oflen(b)crypto bytes.
import "github.com/v8fg/kit4go/random"
code := random.NumericCode(6) // "048213" — SMS OTP
id := random.RandStringWithLetterDigits(16)
pick, _ := random.RandIn([]string{"a", "b", "c"})
tok, _ := random.CryptoInt(1 << 62) // secure range-limited int- For 2FA (time/counter based) use package
otp(TOTP/HOTP), not this package. NumericCodeand theRandString*family are pseudo-random; do not use them for security tokens. PreferCryptoReadString/CryptoInt.