如何跟踪种子

时间:2016-03-03 11:32:36

标签: lua

所以在Lua中你可以使用math.randomseed的常识,但同样显而易见的是math.random也设置种子(调用它两次不会返回相同的结果),它设置了什么,如何跟踪它,如果不可能,请解释为什么会这样。

2 个答案:

答案 0 :(得分:2)

这不是Lua问题,而是关于某些RNG算法如何工作的一般问题。

首先,Lua没有自己的RNG - 他们只是从底层C库的RNG输出(略微损坏的)值。大多数RNG实施都没有向您揭示其内在状态,但有时您可以自己解决它。

例如,当您在Windows上使用Lua时,您将使用来自MS C库的基于LCG的RNG。你得到的数字是一粒种子,而不是全部价值。有两种方法可以解决这个问题:

  1. 如果您知道调用random的次数,则可以获取初始种子值,将其提供给具有在MS库中硬编码的相同常量的相同算法的副本,并获取种子的精确值。
  2. 如果你没有,但你可以确定没有人干扰你的两次随机调用,你可以得到两个生成的数字,并通过将位移回原位来反转LCG算法。这将为您留下几个缺失的位(由于Lua重整而多了一点),您将需要简单地强制执行 - 只需重复所有丢失的位,直到您的算法副本产生完全相同的两个"随机"您之前录制过的数字。那将是存储在库的RNG内的当前种子。在Lua中编程良好的解决方案可以在有些过时的PC上以0.2-0.5s的速度强制执行 - 我已经做到了。这里有关于Crypto.SE的例子,更详细地讨论了这个任务:Predicting values from a Linear Congruential Generator
  3. 第一种方法可以与任何其他不使用任何真实熵的RNG算法一起使用,其次是大多数RNG不会在切片中屏蔽过多的比特,使得暴力不合理。

    真正的答案是:你根本不需要跟踪种子。你想要的可能是其他东西。

答案 1 :(得分:0)

如果设置种子,则生成的所有数字math.random()都是伪随机的(这种情况总是如此,因为系统会自行生成种子)。

math.randomseed(4)
print(math.random())
print(math.random())
math.randomseed(4)
print(math.random())

输出

0.50827539156303
0.75454387490399
0.50827539156303

因此,如果将种子重置为相同的值,则可以预测所有将使用该种子生成的最大连续值数的值。

种子不做的是保持math.random()的输出相同。如果你将它重置为相同的值,它将是相同的。

类比作为例子

想象一下,随机数是0到9之间的整数(而不是0到1之间的双数)。 math.random()可以从任意起始位置遍历pi的小数(默认可以是系统时间)。
当你使用set.seed()时你所做的是(不是字面意思,这是所提到的类比)设置你将要检索你的数字的位置的起始小数。
如果您现在将种子重置为相同的起始位置,则数字将与上次重置起始位置时的数字相同。
您将知道最后一次通话的号码,之后您就无法确定了。