【问题标题】:Did Microsoft change Random default seed?微软是否更改了随机默认种子?
【发布时间】:2020-01-14 05:43:57
【问题描述】:

今天,我在 .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#

Non-repetitive random number

Is C# Random Number Generator thread safe?


我的设置:.NET Core 2.2 / 最新的 C# 编译器。


实际问题

所以我的问题是,PRNG 是否真的得到了改进,或者他们只是更改了构造函数以使用另一个默认种子,如果是,他们使用什么作为种子?现在密码学是否更安全(如果他们真的改变了实现)?

【问题讨论】:

  • Is it safer now for cryptography? 否。如docs:“要生成加密安全随机数,例如适合创建随机密码的随机数,请使用 RNGCryptoServiceProvider 类或从 System. Security.Cryptography.RandomNumberGenerator"
  • 问题是你一次又一次地重新创建一个新的Random。您应该只创建一次。
  • @HimBromBeere 我知道,这正是我要说的。在旧版本上,它会多次重复该数字,但在新版本上则不会。
  • @dyukha 我也这么想,但如果它的内部结构发生了变化(我不确定),那么他们可能做了一些额外的事情。不确定。
  • @AxelKemper 我相信参考资源已经过时了。它使用默认构造函数作为 TickCount,如果我直接使用 Environment.TickCount,我将得到旧的和重复的结果。

标签: c# random


【解决方案1】:

在最新版本的 dotnet core 中,Random 默认构造函数从 Random 的隐藏私有实例分配其种子。私有实例使用 Interop.GetRandomBytes 作为其种子。新实例使用私有实例的 Next() 结果作为其种子。

这基本上使得在循环中创建多个随机实例变得“安全”。

在 corefx GitHub 上阅读更多信息:

相关代码文件:Private Random InstanceDefault Constructor - Generate Seed Private Random Instance - Generate Seed

种子更改拉取请求Parameterless constructor seeding improvement #1919

【讨论】:

  • 从 .Net Framework 4.8 开始,默认种子仍然是 Environment.TickCount
  • 你知道为什么 corefx 有不同的实现吗?
  • 不确定,但我猜微软主要在 dotnet core 上工作,允许多个实例更安全,而不是因为拥有多个实例而留下不需要的结果。即使多个实例不在一个紧密的循环中,也可能在不同的类中存在多个实例。
  • 也许是想摆脱环境? .net 核心应该与平台无关,因此它们不会转发 Enviroment.TickCount
  • 在 GitHub 上对 corefx 问题进行了一番挖掘后,我找到了this one related to the random seed,其中引用了this discussion
猜你喜欢
  • 2022-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-30
  • 1970-01-01
  • 1970-01-01
  • 2022-09-27
  • 2014-06-01
相关资源
最近更新 更多