Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a true random [duplicate]

Tags:

c#

random

Possible Duplicate:
Why does it appear that my random number generator isn't random in C#?
How can I generate truly (not pseudo) random numbers with C#?

I've created a dice game where the dice is based on a percentile, 1-100.

public static void Roll()
{
    Random rand = new Random((int)DateTime.Now.Ticks);
    return rand.Next(1, 100);
}

But I don't feel like it's a real random based on current time.

If I do

for (int i = 0; i < 5; i++)
{
   Console.WriteLine("#" + i + " " + Roll());
}

They would all be the same values, because the DateTime.Now.Ticks didn't change, it seeded the same number.

I was thinking I could generate a new random seed if the seed was the same due to the current time, but it doesn't feel like an honest "re-roll"

What should I do to try and replicate a close to real/honest dice roll? Should I use the RNGCryptoServiceProvider class to generate rolls instead?

like image 628
Kyle Avatar asked Nov 29 '11 09:11

Kyle


People also ask

Can we generate true randomness?

Computational random number generators can typically generate pseudorandom numbers much faster than physical generators, while physical generators can generate "true randomness."

What is the best method to generate true random numbers?

There are two main methods that a computer generates a random number: true random number generators (TRNGs) and pseudo-random number generators (PRNGs). The former uses some phenomenon outside the computer for its number generation, whereas the latter relies on pre-set algorithms to emulate randomness².

Is TRNG better than PRNG?

A PRNG is much faster than a TRNG, hence it is common to generate a seed using a TRNG to initialize a PRNG. After that, the PRNG generates the random numbers. In the Linux kernel /dev/random uses an entropy pool to generate random data.

Why is true randomness impossible?

Randomness is relational. The problem modern computers have with randomness is that it doesn't make mathematical sense. You can't program a computer to produce true randomness—wherein no element has any consistent, rule-based relationship to any other element—because then it wouldn't be random.


1 Answers

DateTime.Now.Ticks only has a resolution of approximately 16ms, so if you create a Random with that overload multiple times within a 16ms "slot" they will all be seeded with the same value and therefore you will get the same sequence.

Initialize your Random outside your loop so that a single Random sequence is produced, rather than creating it each time within the loop which could result in Randoms being seeded with the same value and so produce the same sequence.

Update

My previous point that the default constructor initialized Random with CPU ticks was incorrect, the default constructor actually uses Environment.TickCount which is:

A 32-bit signed integer containing the amount of time in milliseconds that has passed since the last time the computer was started.

Which still has a low resolution. If you make multiple instances of Random in quick succession, they can easily be created within the same time slot and therefore have the same seed value, and create the same sequence. Create a single instance of Random and use that.

Update

Further to your comments, if you wish to generate a random sequence across multiple threads, please see the following Jon Skeet article which discusses a thread-safe wrapper:

https://codeblog.jonskeet.uk/2009/11/04/revisiting-randomness

like image 89
Tim Lloyd Avatar answered Sep 20 '22 06:09

Tim Lloyd