Math/rand and crypto/rand differences


(Raphael Spannocchi) #1

Hi y’all!

First thanks to anybody that spends the time to read this.
I’m new to Go and just found two rand packages, and got fascinated by the differences.


This discussion is extremely enlightening, but for those of you who are new to Go, like me, it might be interesting to really see the randomness of the random number generators in action.

The little program I wrote is basically my try to understand Rob Pikes fan in pattern.
Rob Pike’s code here: https://play.golang.org/p/buy30qw5MM

I wrote a similar program where a generator generates random numbers between 1 and 6 and so simulates a dice roll.
Two of these generators are launched concurrently and then a collector goroutine adds up the tally of each of the generators.

This example uses math/rand:
https://play.golang.org/p/XsmG927YuZi

And this example uses crypto/rand:
https://play.golang.org/p/6qIsnZUzRGE

The first example has maybe 2 possible outcomes across all 10 rolls, usually just 1!
The second is more in line with what I’d expect from dice rolls. Sometimes A wins, sometimes B wins.

So, what I learned is: Whenever I want numbers to be random, for any games e.g., I need to use crypto/rand.

Am I getting this wrong?
Any comments on the code also greatly welcome.

Thanks,
Raphael


( Kvaz1r) #2

You didn’t notice that you can change Seed for math/rand package for generating different sequence of number. Also as generator source.
Rand from math package use some known algorithm for generating pseudo-random numbers while rand from crypto use real random when it possible. But it costs much more.

From my point of view math/rand package can be used for simple games, but not when expected truly randomness.


(Raphael Spannocchi) #3

Ah! Thanks a lot!
That would be with the rand.Seed(seed int64) method?
But how would I do that in a game?
I’d have to find a source for the seeds…


( Kvaz1r) #4

Usually it’s like so when game starting:

rand.Seed(time.Now().UnixNano())


(Raphael Spannocchi) #5

Got it! Thanks for the valuable info!


(Johann Forster) #6

Some more about this topic:

The official ioutil.TempFile function (see https://golang.org/src/io/ioutil/tempfile.go) which creates temporary files with random names uses easy Numerical Recipes and seeds with time.Now().UnixNano() + int64(os.Getpid()).


(Raphael Spannocchi) #7

another good one! thanks!!

very clever


(Raphael Spannocchi) #8

Hey, I tried that, and at least in the Go Playground, the seed stays the same, over minutes.
See here:
https://play.golang.org/p/jGi7LjzFUQC


(Raphael Spannocchi) #9

On my computer it works fine. It must be some property of the Go Playground.
Fascinating.


(Ignacio Gómez) #10

It is, in the playground the time is fixed as explained here:

In the playground the time begins at 2009-11-10 23:00:00 UTC (determining the significance of this date is an exercise for the reader). This makes it easier to cache programs by giving them deterministic output.


(Raphael Spannocchi) #11

Thanks Mr. Gomez.

Well appreciated!


(system) closed #12

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.