繁体   English   中英

我应该播种随机数生成器吗?

[英]Should I seed the random number generator?

从文档:

random.seed(a=None, version=2) 初始化随机数生成器。

如果省略 a 或 None,则使用当前系统时间。 如果操作系统提供随机源,则使用它们而不是系统时间(有关可用性的详细信息,请参阅 os.urandom() 函数)。

但是......如果它真的是随机的......(我认为我读到它使用梅森,所以它非常随机)......播种它有什么意义? 无论哪种方式,结果都是不可预测的......对吧?

如果您希望每次运行都有不同的随机数,则默认值可能是最好的。 如果出于某种原因您需要可重复的随机数,例如在测试中,请使用种子。

但是……如果真的是随机的

不,这是伪随机。 如果它使用 Mersenne Twister,那也是PRNG

它基本上是一种算法,可以从给定的种子中生成完全相同的伪随机数序列。 生成真正的随机数需要特殊的硬件支持,这不是纯算法可以做到的。

您可能不需要播种它,因为它会在第一次使用时播种,除非您有其他或更好的方法来提供种子而不是基于时间的方法。

如果您将随机数用于与安全无关的事情,则基于时间的种子通常没问题。 如果您将 if 用于安全/加密,请注意文档中的内容:“并且完全不适合用于加密目的”

当您导入模块时,该模块实际上会为生成器设置种子(如果可能,使用操作系统提供的来自urandom随机数据,否则使用当前日期和时间),因此无需手动调用seed()

(这是在 Python 2.7 文档中提到的,但出于某种原因,不是 3.x 文档。但是,我在 3.x 源代码中确认它仍然完成。)

如果没有自动播种,每次启动程序时都会得到相同的数字序列,就像每次手动使用相同的种子一样。

如果你想重现你的结果,你可以用一个已知的值给生成器做种子,这样你每次都能得到相同的序列。

一个 Mersenne twiner,即 Python 使用的随机数生成器,在可能的平台(Unixen、Windows)上由操作系统默认提供随机数种子; 但是在其他平台上,种子默认为系统时间,这意味着如果系统时间精度不佳,则值非常可重复。 在这样的系统上,使用已知更好的随机值进行播种是有益的。 请注意,特别是在 Python 3 上,如果使用版本 2,您可以传入任何strbytesbytearray来为生成器提供种子; 从而更好地利用梅森捻线机的大状态。

使用种子值的另一个原因确实是为了保证您一次又一次地获得相同的随机数序列——通过重用已知的种子。 引用文档

有时,能够重现伪随机数生成器给出的序列很有用。 通过重新使用种子值,只要多个线程没有运行,相同的序列就应该可以从运行到运行重现。

大多数 random 模块的算法和播种函数可能会在 Python 版本之间发生变化,但有两个方面保证不会发生变化:

  • 如果添加了新的播种方法,则将提供向后兼容的播种机。
  • 当兼容的种子被赋予相同的种子时,生成器的 random() 方法将继续产生相同的序列。

但是,为此,您主要希望使用random.Random实例而不是使用模块全局方法(多线程问题等)。

最后还要注意,Mersenne twiner 产生的随机数不适合加密使用; 虽然它们看起来非常随机,但可以通过仅观察来自生成器的数百个值来完全恢复随机生成器的内部状态。 对于加密算法,您希望使用SystemRandom

在大多数情况下,我会说没有必要关心。 但是,如果有人真的愿意做一些有线的事情,并且(她)他可以粗略地计算出您的代码运行时的系统时间,那么他们可能能够蛮力重放您的随机数并查看哪个系列适合。 但我会说在大多数情况下这是不太可能的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM