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)?
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).
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With