Wednesday, May 09, 2018

Easier random numbers in Go

Abstract: Replace import "math/rand" with import "" and get high-quality random numbers every time.

Like many Go developers, I use Go's math/rand package for generating random numbers.  That package defaults to a predictable stream of outputs, so you have to seed the generator if you actually want random numbers. I'm embarrassed to admit how often I've forgotten to seed the generator.  In large projects, I see the generator being seeded multiple times across different files because everyone wants to be certain the generator has been seeded.

Even if I do remember to set a seed, I often get hung up on other questions like:
  • is my seed good enough?
  • are these random numbers high enough quality for my application?
  • do I need to reseed the generator after a while?
  • how often?
I just want random numbers without all this complexity.

More than 20 years ago, OpenBSD developers were seeing similar problems.  In 1996, they addressed it by introducing arc4random.  You call the function and get a high-quality random number every single time.  There's no seeding, no failure mode, no need to consume file handles, just random numbers.  It's refreshingly simple.

I wanted that same simplicity in Go, so I wrote  It's just a thin wrapper around Go's crypto/rand which gives those high-quality numbers the same clean interface as math/rand.  In many cases, you can just replace import "math/rand" in your code with import "" then delete your calls to math.Seed() and everything works.

No comments: