在C#中播种伪随机数生成器

Dan*_*ker 16 c# random gethashcode

我需要一个C#Random类实例的种子,我读到大多数人使用当前时间的滴答计数器.但这是一个64位值,种子需要是32位值.现在我认为GetHashCode()返回a 的方法int应该为其对象提供合理分布的值,这可以用于避免仅使用滴答计数的低32位.但是,我找不到任何有关Int64数据类型的GetHashCode()的信息.

所以,我知道它并不重要,但是下面的工作会像我想的那样好(我不能试错法随机性),或者它可能与使用(int)DateTime.Now.Ticks种子一样工作吗?或者甚至可能更糟糕?谁可以对此有所了解.

int seed = unchecked(DateTime.Now.Ticks.GetHashCode());
Random r = new Random(seed);
Run Code Online (Sandbox Code Playgroud)

编辑:为什么我需要种子而不只是让Random()构造函数完成工作?我需要将种子发送给使用相同种子的其他客户端进行相同的随机序列.

Cod*_*aos 34

new Random()已经使用了当前时间.它相当于new Random(Environment.TickCount).

但这是一个实现细节,可能会在.net的未来版本中发生变化

我建议使用新的Random(),如果你想得到一个可重现的伪随机值序列,只提供一个固定的种子.

因为你需要一个已知的种子Environment.TickCount,就像MS一样.然后将其作为种子传输到其他程序实例.

如果Random在短间隔(可能是16ms)中创建多个实例,则可以将它们播种到相同的值,从而创建相同的伪随机序列.但这很可能不是问题.这种常见的陷阱是由Windows 仅每隔几毫秒更新当前时间(DateTime.Now/ .UtcNow)和TickCount(Environment.TickCount)引起的.确切的间隔取决于Windows的版本以及正在运行的其他程序.它们不变的典型间隔是16ms或1ms.

  • +1提及真正提供自己的种子值的唯一时间是当您想要重现特定的值序列时.按照Windows Solitaire"游戏编号"选项的思路进行思考. (2认同)

ste*_*nar 30

如果你需要用当前时间之外的东西来种子(在这种情况下你可以使用默认的构造函数),你可以使用:

Random random = new Random(Guid.NewGuid().GetHashCode());
Run Code Online (Sandbox Code Playgroud)

  • 它更好,因为它不会遇到"DateTime.Now"每隔几毫秒才会改变的问题.使用这种方法,即使在快速连续初始化时,两个随机实例也不太可能获得相同的种子. (17认同)
  • 为什么这比'DateTime.Now.Ticks.GetHashCode()`更好? (3认同)