author
Kevin Kelche

Generate Random Numbers in Golang


In Go, the math/rand package provides a source of random numbers. It is important to know that these numbers are not random since they are generated by a deterministic algorithm, and thus termed pseudo-random. To generate cryptographically secure random numbers, use the crypto/rand package. This is a good practice to follow when generating random numbers for security purposes i.e. generating passwords, tokens, API keys, etc. In this article, we will learn how to generate random numbers in Go.

Generating Random Numbers

Integers

To generate random integers, rand.Intn() is used. This function takes an integer as an argument and returns an integer between 0 and the argument and throws an error if the argument is less than 0. For example, to generate a random integer between 0 and 100, we can use the following code:

package main

import (
  "fmt"
  "math/rand"
)

func main() {
  fmt.Println(rand.Intn(100))
}

Copied!

By running this code you find out that it only generates 81 as its random number. This is because the rand package uses a global source of random numbers. This means that the same sequence of random numbers is generated every time the program is run. To generate a different sequence of random numbers, we need to seed the global source of random numbers. This can be done by calling the rand.Seed() function which takes an integer as an argument and uses it to seed the global source of random numbers. For example, to generate a random integer between 0 and 100 just as intended above, we can use the following code:

package main

import (
  "fmt"
  "math/rand"
  "time"
)

func main() {
  rand.Seed(time.Now().UnixNano())
  fmt.Println(rand.Intn(100))
}

Copied!

We need to pass a constantly changing value to the rand.Seed() function to generate a different sequence of random numbers every time the program is run. That is why we are using the time.Now().UnixNano() function to get the current time in nanoseconds.

Floats

To generate random floats, rand.Float64() is used. This function returns a float64 between 0 and 1. For example, to generate a random float between 0 and 100, we can use the following code:

package main

import (
  "fmt"
  "math/rand"
  "time"
)

func main() {
  rand.Seed(time.Now().UnixNano())
  fmt.Println(rand.Float64() * 100)
}

Copied!

Generating Random Numbers in a Range

To get a random number from a given range, we can still use the rand.Intn() function and pass the range argument then add the minimum value to the result. For example, to generate a random integer between 10 and 20, we can use the following code:

package main

import (
  "fmt"
  "math/rand"
  "time"
)

func main() {
  rand.Seed(time.Now().UnixNano())
  fmt.Println(rand.Intn(10) + 10)
}

Copied!

Generating random permutations and sequences

A permutation is a sequence of numbers in which each number is unique. To generate a random permutation of numbers, we can use the rand.Perm() function. This function takes an integer as an argument and returns a slice of integers between 0 and the argument. For example, to generate a permutation of numbers between 0 and 10, we can use the following code:

package main

import (
  "fmt"
  "math/rand"
  "time"
)

func main() {
  rand.Seed(time.Now().UnixNano())
  fmt.Println(rand.Perm(10))
}

Copied!

Generating cryptographically secure random numbers

As mentioned earlier, the rand package is unsuitable for generating cryptographically secure random numbers. We need to use the crypto/rand package to generate cryptographically secure random numbers. This package provides functions for generating random numbers suitable for security applications. For example, to generate a random integer between 0 and 100, we can use the following code:

package main

import (
  "crypto/rand"
  "fmt"
  "math/big"
)

func main() {
  n, err := rand.Int(rand.Reader, big.NewInt(100))
  if err != nil {
    fmt.Println(err)
  }
  fmt.Println(n)
}

Copied!

And that’s it! You now know how to generate random numbers in Go.

Subscribe to my newsletter

Get the latest posts delivered right to your inbox.