As a practical programming example, this section will talk about creating random numbers in Go. Random numbers have many uses, including the generation of good passwords as well as the creation of files with random data that can be used for testing other applications. However, bear in mind that usually programming languages generate pseudorandom numbers that approximate the properties of a true random number generator.
Go uses the math/rand package for generating random numbers and needs a seed to start producing random numbers. The seed is used for initializing the entire process and is extremely important because if you always start with the same seed, you will always get the same sequence of random numbers.
The random.go program has three main parts. The first part is the preamble of the program:
package main
import (
"fmt"
"math/rand"
"os"
"strconv"
"time"
)
The second part is the definition of the random() function that returns a random number each time it is called, using the rand.Intn() Go function:
func random(min, max int) int {
return rand.Intn(max-min) + min
}
The two parameters of the random() function define the lower and upper limits of the generated random number. The last part of random.go is the implementation of the main() function that is mainly used for calling the random() function:
func main() {
MIN := 0
MAX := 0
TOTAL := 0
if len(os.Args) > 3 {
MIN, _ = strconv.Atoi(os.Args[1])
MAX, _ = strconv.Atoi(os.Args[2])
TOTAL, _ = strconv.Atoi(os.Args[3])
} else {
fmt.Println("Usage:", os.Args[0], "MIX MAX TOTAL")
os.Exit(-1)
}
rand.Seed(time.Now().Unix())
for i := 0; i < TOTAL; i++ {
myrand := random(MIN, MAX)
fmt.Print(myrand)
fmt.Print(" ")
}
fmt.Println()
}
A big part of the main() function involves dealing with the reading of command-line arguments as integer numbers and printing a descriptive error message in case you did not get the correct number of command-line arguments. This is the standard practice that we will follow in this book. The random.go program uses the Unix epoch time as the seed for the random number generator by calling the time.Now().Unix() function. The important thing to remember is that you do not have to call rand.Seed() multiple times. Lastly, random.go does not examine the error variable returned by strconv.Atoi() to save book space, not because it is not necessary.
Executing random.go generates the following kind of output:
Should you wish to generate more secure random numbers in Go, you should use the crypto/rand package, which implements a cryptographically secure pseudorandom number generator. You can find more information about the crypto/rand package by visiting its documentation page at https://golang.org/pkg/crypto/rand/.
If you are really into random numbers, then the definitive reference to the theory of random numbers is the second volume of The Art of Computer Programming by Donald Knuth.