Go random
last modified August 30, 2026
In this article we show how to generate random values in Go. We use
math/rand/v2 for ordinary pseudo-random values and
crypto/rand when the values must be unpredictable.
Random number generator
Random number generator (RNG) generates a set of values that do not display any distinguishable patterns in their appearance. The random number generators are divided into two categories: hardware random-number generators and pseudo-random number generators. Hardware random-number generators are believed to produce genuine random numbers. Pseudo-random number generators generate values based on software algorithms. They produce values that look random. But these values are deterministic and can be reproduced, if the algorithm is known.
In computing, random generators are used in gambling, gaming, simulations, or cryptography.
Cryptographically secure generators obtain entropy from the operating system. They are designed to resist prediction and are appropriate for secrets; they are usually slower than ordinary pseudo-random generators.
Go contains the math/rand/v2 package, which implements ordinary
pseudo-random number generators, and the crypto/rand package, which
implements a cryptographically secure random number generator.
The seed
The seed is a value which initializes the random number generator. Random number generators produce values by performing some operation on a previous value. When the algorithm starts, the seed is the initial value on which the generator operates. The most important and difficult part of the generators is to provide a seed that is close to a truly random number.
For reproducible pseudo-random values, create a local generator with an
explicit seed. The package-level functions in math/rand/v2 are
automatically seeded for ordinary use, so application code does not need to
seed them with the current time.
Go random same seed
In the following example, we use the same seed.
package main
import (
"fmt"
"math/rand/v2"
)
func main() {
first := rand.New(rand.NewPCG(20, 10))
fmt.Printf("%d ", first.IntN(100))
fmt.Printf("%d ", first.IntN(100))
fmt.Printf("%d \n", first.IntN(100))
second := rand.New(rand.NewPCG(20, 10))
fmt.Printf("%d ", second.IntN(100))
fmt.Printf("%d ", second.IntN(100))
fmt.Printf("%d \n", second.IntN(100))
fmt.Println()
}
The same seed values produce the same pseudo-random values. The two 64-bit
values passed to NewPCG initialize the generator state.
NewPCG returns a generator based on the PCG (permuted
congruential generator) algorithm, which is the default generator of
math/rand/v2. The function takes two 64-bit seed values,
seed1 and seed2, which together form the initial
state of the generator. Generators created with the same seed values produce
the same sequence of pseudo-random numbers; using different seed values
produces different sequences.
$ go run same_seed.go 6 2 3 6 2 3
Go rand.IntN
The rand.IntN function returns, as an int, a non-negative
pseudo-random number in [0,n) from the default source.
package main
import (
"fmt"
"math/rand/v2"
)
func main() {
for i := 0; i < 5; i++ {
fmt.Printf("%d ", rand.IntN(20))
}
fmt.Println()
}
The example prints five random integers.
rand.IntN(20)
The package-level generator is automatically seeded, so repeated runs normally produce different values without any explicit time-based seed.
Go random string
The following example generates random strings.
package main
import (
"fmt"
"math/rand/v2"
)
func main() {
fmt.Println(randomString(12))
}
func randomString(length int) string {
bytes := make([]byte, length)
for i := 0; i < length; i++ {
bytes[i] = byte('a' + rand.IntN(26))
}
return string(bytes)
}
The example creates a random string having twelve characters.
$ go run random_string.go gqvqyybfuhxl $ go run random_string.go rrwmqaqkrslu $ go run random_string.go axhhrkwyhnxm
We run the example three times. The output changes because the package-level generator is automatically seeded.
Go random array of integers
The following example creates an array of random integer values.
package main
import (
"fmt"
"math/rand/v2"
)
func randArray(len int) []int {
a := make([]int, len)
for i := 0; i < len; i++ {
a[i] = rand.IntN(len)
}
return a
}
func main() {
len := 12
fmt.Println(randArray(len))
}
The example creates an array of twelve integer values.
$ go run rand_array.go [5 6 3 5 3 4 7 3 5 6 5 0] $ go run rand_array.go [2 5 10 9 1 5 1 4 11 7 6 3]
Go random element
The following example picks a random element.
package main
import (
"fmt"
"math/rand/v2"
)
func main() {
runes := []rune("červená čiara")
myrune := runes[rand.IntN(len(runes))]
fmt.Println(string(myrune))
}
We have a slice of runes. From this slice, we randomly pick a value.
$ go run random_element.go č $ go run random_element.go á
We ran the example twice and get these characters.
Go random string from a pool
The following example picks letters randomly from a pool of characters.
package main
import (
"fmt"
"math/rand/v2"
)
var pool = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ:|?$%@][{}#&/*)"
func randomString(l int) string {
bytes := make([]byte, l)
for i := 0; i < l; i++ {
bytes[i] = pool[rand.IntN(len(pool))]
}
return string(bytes)
}
func main() {
fmt.Println(randomString(12))
}
The example prints random strings from the predefined pool of various characters.
var pool = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ:|?$%@][{}#&/*)"
This is the set of predefined characters.
for i := 0; i < l; i++ {
bytes[i] = pool[rand.IntN(len(pool))]
}
We pick a random letter by generating a random index of the string.
$ go run rand_pool.go
FFFZW(sHvE:a
$ go run rand_pool.go
(my%Tmf&qOVs
$ go run rand_pool.go
/{GqgkhRVOfi
We run the example three times.
Go crypto-secure random values
Go provides a cryptographically secure pseudorandom number generator in the
standard library package crypto/rand. math/rand/v2 is
usually faster and is suited for ordinary values, while crypto/rand
is suited for programs where security is paramount, such as when generating
strong passwords, CSRF tokens, or session keys.
On Linux and FreeBSD, crypto/rand uses getrandom
if available, and /dev/urandom otherwise. On OpenBSD, it uses
getentropy. On Unix-like systems, it reads from the operating
system's secure random source. On Windows systems, it uses the system
cryptographic random source. On Wasm, it uses the Web Crypto API.
package main
import (
"crypto/rand"
"fmt"
"log"
)
func main() {
data, err := generateRandomBytes(16)
if err != nil {
log.Fatal(err)
}
fmt.Println(data)
}
func generateRandomBytes(n int) ([]byte, error) {
b := make([]byte, n)
_, err := rand.Read(b)
if err != nil {
return nil, err
}
return b, nil
}
In the code example, we create 16 securely generated random bytes.
b := make([]byte, n) _, err := rand.Read(b)
We read n cryptographically secure pseudorandom numbers and write
them into a byte slice.
$ go run crypto_rand.go [151 0 67 88 199 60 220 50 34 198 169 158 18 162 85 61]
Source
Go math/rand/v2 package - reference
Go crypto/rand package - reference
In this article we have worked with random values in Golang.
Author
List all Go tutorials.