Compare math/rand, math/rand/v2 and crypto/rand. What changed about seeding in Go 1.20 and 1.22, and when must you use crypto/rand?
Question 535MediumGo 1.22 to 1.25
math/rand and math/rand/v2 are fast pseudo-random generators whose output can be predicted. crypto/rand reads from the OS CSPRNG (getrandom, BCryptGenRandom and so on).
- Go 1.20: the global
math/randsource is seeded randomly at startup, so programs no longer produce the same sequence on every run by default.rand.Seedis deprecated. - Go 1.22: adds
math/rand/v2. It has no globalSeedat all, names likeIntNandUint64, a genericrand.N, and the betterPCGandChaCha8sources. The global generator is ChaCha8-based and safe for concurrent use. - Go 1.24: the top-level
math/rand.Seedbecomes a no-op unlessGODEBUG=randseednop=0. For reproducible sequences, create your own generator withrand.New(src).
import (
crand "crypto/rand"
"math/rand/v2"
"time"
)
n := rand.IntN(100) // [0,100)
jitter := rand.N(500 * time.Millisecond) // generic over integer types, incl. Duration
r := rand.New(rand.NewPCG(1, 2)) // deterministic stream for tests/simulations
_ = r.IntN(10)
token := crand.Text() // Go 1.24: 26-char base32 secure string
key := make([]byte, 32)
crand.Read(key) // Go 1.24+: never returns an error (crashes on failure)
When you must use crypto/rand: session IDs, API tokens, password-reset links, keys, nonces, salts, and anything an attacker gains from guessing. math/rand is for jitter, shuffling, sampling and simulations. crypto/rand.Int gives you an unbiased big integer in a range.
More on More Standard Library Essentials
- Q533Compare sort.Slice, sort.SliceStable, sort.Sort (sort.Interface) and slices.SortFunc. Which are stable, and what are the performance differences?
- Q534How does Go's time layout work (the reference time Mon Jan 2 15:04:05 MST 2006)? What bugs come from using "2006-01-02" vs "YYYY-MM-DD", time zones and time.Parse vs time.ParseInLocation?
- Q536text/template vs html/template: how does contextual auto-escaping prevent XSS, and what does template.HTML bypass?
- Q537How do you prevent SQL injection with database/sql? Why can't placeholders be used for table names or ORDER BY columns?
- Q538Why should you compare secrets with crypto/subtle.ConstantTimeCompare instead of ==? How do you hash passwords in Go?
- Q539How does regexp (RE2) differ from PCRE engines? Why doesn't Go support backreferences, and what are the performance guarantees?