math/rand package provided by the Go Standard Library gives us pseudo-random number generators (PRNG), also called deterministic random bit generators.
As with all pseudo number generators, any number generated through
math/rand is not really random by default, as being deterministic it will always print the same value each time.
As an example, try running this code which introduces
rand.Intn(n), which returns a random number between
n - 1.
You’ll always see the same sequence every time you run the program. The random number changes inside the program, but every time you run it, you’ll get the same output:
This is because by default the seed is always the same, the number 1. To actually get a random number, you need to provide a unique seed for your program. You really want to not forget seeding, and instead properly seed our pseudonumber generator. How?
rand.Seed() before calling any
math/rand method, passing an
int64 value. You just need to seed once in your program, not every time you need a random number. The most used seed is the current time, converted to
int64 by UnixNano with
Remember that due to its sandboxing, the Go Playground always begins with the same time, so this code won’t work as expected. Try it on a real environment, and the numbers that previosly didn’t change, they will now print differently each time you run the program.
Some common examples are listed below for ease of reuse:
Will return 10 chars in uppercase format. Change
bytes[i] = byte(randomInt(65, 90))
bytes[i] = byte(randomInt(97, 122))
for just lowercase.
If you instead want to have a pool of specific chars to pick from, use
Change len(pool) to utf8.RuneCountInString(pool) if you use non-ascii strings, as len() counts the bytes, but not all chars take just one byte in Unicode - see https://stackoverflow.com/questions/12668681/how-to-get-the-number-of-characters-in-a-string.
Go also provides a Cryptographically secure pseudorandom number generator (CSPRNG) in the standard library package crypto.rand
So you might question, why should I even use the pseudo-number random generator library provided by
math/rand instead? Well, it depends on the use case.
math/rand is much faster for applications that don’t need crypto-level or security-related random data generation. crypto.rand is suited for secure and crypto-ready usage, but it’s slower.
What it should be used for? For example, generating passwords, CSRF tokens, session keys, or anything remotely related to security.
It does not rely on the current time, like we did in the previous examples in math/rand, but instead it uses the operating system CSPRNG APIs: the CryptGenRandom API on Windows, and
/dev/urandom/ on all the others (
Linux, OSX, *nix)
You get 256 random bytes directly with
I’m taking a code sample from Matt Silverlock: you can make it more general and create a random bytes generation function
// GenerateRandomBytes returns securely generated random bytes.
and using this, a random string generation function,
// GenerateRandomString returns a URL-safe, base64 encoded