[Golang] Seed Pseudorandom Number Generator (PRNG) Properly


In my previous post, I use the pseudo random number generator (PRNG) of Go standard math/rand package to generate random string as follows:

package mylib

import (
      "math/rand"
      "time"
)

func RandomString(strlen int) string {
      // seed the PRNG
      rand.Seed(time.Now().UTC().UnixNano())

      // generate randsom string with rand.Intn method
}

As you can see, I seed the PRNG on each use because I have no idea what is the proper way to use the PRNG.

@dchapes left a comment to tell me something I do not know before:

  • Do not re-seed PRNGs on each use.
  • Do not re-seed the global PRNG in a package.

So I did some googling [1] [2], and at the same time @shurcooL left another comment to show me how to properly seed the PRNG:

If you're using global rand.Rand, don't re-seed it. But if you want to set your own seed, create your own local instance of rand.Rand.

var r *rand.Rand // Rand for this package.

func init() {
    r = rand.New(rand.NewSource(time.Now().UnixNano()))
}

func RandomString(strlen int) string {
    // use existing r, no need to re-seed it
    r.Intn(len(chars))
}

You can also simplify this into one line:

// r is a source of random numbers used in this package.
var r = rand.New(rand.NewSource(time.Now().UnixNano()))

According to above comments, the most proper way to seed the PRNG in my case is as follows:

package mylib

import (
      "math/rand"
      "time"
)

// r is a source of random numbers used in this package.
var r = rand.New(rand.NewSource(time.Now().UnixNano()))

func RandomString(strlen int) string {
      // generate randsom string with r.Intn method
}

You can see my post for complete example of using PRNG to generate random string. [3]


Tested on: Ubuntu Linux 16.10, Go 1.8.


References:

[1]
[2]go - Golang random number generator how to seed properly - Stack Overflow
[3][Golang] Generate Random String From [a-z0-9]