今天,我在.NET Core 中做一些测试,遇到了一些有趣的事情。
在 (~ .NET Framework 4) 之前,Random
使用了 Environment.TickCount
,但现在我相信这已经改变了。
考虑以下代码:
while (true)
{
Random random = new Random();
Console.WriteLine(random.Next(0, 10000));
}
在旧的 .NET Framework 版本中,new Random()
空构造函数将使用 Environment.TickCount,这将导致伪随机值的重复。
所以你可以期待这样的结果:
542
4211
5244
5244
5244
9501
9501
以此类推。
在使用最新编译器的最新 .NET Core 版本上,我收到了以下结果:
5332
220
3928
524
2973
2840
4965
5667
657
6434
3170
3046
7044
这绝对是改进了。
在旧版本中展示此行为的其他 S.O 问题:
How do I generate a random int number?
generate random numbers with no repeat in c#
Is C# Random Number Generator thread safe?
我的设置:.NET Core 2.2/最新的 C# 编译器。
实际问题
所以我的问题是,PRNG 是否真的得到了改进,或者他们只是更改了构造函数以使用另一个默认种子,如果是的话,他们使用什么作为种子?现在对于密码学来说是否更安全(如果他们真的改变了实现)?
最佳答案
在最新版本的 dotnet 核心中,Random
默认构造函数从 Random
的隐藏私有(private)实例分配其种子。私有(private)实例使用 Interop.GetRandomBytes 作为其种子。新实例使用私有(private)实例的 Next()
结果作为其种子。
这基本上使得在循环中创建多个随机实例变得“安全”。
在 corefx GitHub 上阅读更多内容:
相关代码文件:Private Random Instance , Default Constructor - Generate Seed 和 Private Random Instance - Generate Seed .
种子更改拉取请求 Parameterless constructor seeding improvement #1919
关于c# - 微软是否更改了随机默认种子?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57905143/