Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Did Microsoft change Random default seed?

Tags:

c#

random

Today, I was doing some tests in .NET Core, and I have come across some interesting thing.

Before (~ .NET Framework 4), Random used Environment.TickCount, but now I believe this has changed.

Consider the following code:

while (true)
{
    Random random = new Random();
    Console.WriteLine(random.Next(0, 10000));
}

In older .NET Framework versions, the new Random() empty constructor would use Environment.TickCount, which would lead to repetition of pseudo-random values.

So you could expect results like:

542
4211
5244
5244
5244
9501
9501

so on and so fourth.

On the latest .NET Core version using the latest compiler, I have received the following result:

5332
220
3928
524
2973
2840
4965
5667
657
6434
3170
3046
7044

Which is definitely improved.

Other S.O questions demonstrating this behaviour in older versions:

How do I generate a random int number?

generate random numbers with no repeat in c#

Non-repetitive random number

Is C# Random Number Generator thread safe?


My setup: .NET Core 2.2 / latest C# compiler.


The actual question

So my question is, has the PRNG really improved or they just changed constructor to use another default seeds, and, if so, what they're using as a seed? Is it safer now for cryptography (if they actually changed the implementation)?

like image 986
Lucca Ferri Avatar asked Sep 12 '19 10:09

Lucca Ferri


People also ask

What is random seed in Excel?

A random seed specifies the start point when a computer generates a random number sequence. This can be any number, but it usually comes from seconds on a computer system's clock (Henkemans & Lee, 2001).

How does random class work in c#?

The current implementation of the Random class is based on a modified version of Donald E. Knuth's subtractive random number generator algorithm. Every time you do new Random() it is initialized using the clock. This means that in a tight loop you get the same value lots of times.


1 Answers

In the latest version of dotnet core, the Random default constructor assigns its seed from a hidden private instance of Random. The private instance uses Interop.GetRandomBytes for its seed. New instances use the private instances's Next() result as its seed.

This basically makes it 'safe' to create several random instances in a loop.

Read more on the corefx GitHub:

Related code files: Private Random Instance, Default Constructor - Generate Seed and Private Random Instance - Generate Seed.

Seed change pull request Parameterless constructor seeding improvement #1919

like image 154
Luke Parker Avatar answered Nov 02 '22 08:11

Luke Parker