当随机数生成器被播种时,rand() 是否确实产生了一个随机值?

Kai*_*aha 1 c random random-seed

我知道为了避免重复rand()函数的相同输出,伪随机数生成器必须与srand函数一起播种。这意味着,如果我尝试 say srand(1), 的输出rand()将是一个值,如果我尝试srand(2),输出将包含另一个值。但是当我再次尝试第一个参数时srand(1),该值将与第一个输出中的值相同。这个问题让我认为所有随机值都可以以某种方式预测。同一个种子是否可以有不同的输出(比如我明天尝试同一个种子)?还是随机值确实可以预测?

tem*_*def 6

对于伪随机生成器的传统定义,如果您知道生成器的种子是什么,那么输出值的序列是完全确定的,而不是随机的。这意味着,如果您知道随机生成器的种子,那么您就可以预测该生成器从那时起将产生的每个输出。(一个好的随机数生成器是这样一个生成器的输出序列不能让你轻松地逆向工程随机种子是什么或预测其他值。)

我似乎记得不久前读到过,一些流行的扑克网站在选择随机种子方面做得并不好。有些人发现你可以输入你看到的卡片的模式,然后系统可以对随机种子进行逆向工程,让你预测所有未来的卡片。哎呀。如今,我们拥有基于加密例程的加密安全伪随机生成器,至少在公开文献中已知的情况下,即使您有来自生成器的数千兆字节的随机输出,也无法预测。

如果你确实需要得到一些真正不可预测的东西——也就是说,你想得到一堆真正的随机位——你​​需要使用伪随机数生成器以外的东西。大多数操作系统都有一些机制来生成看似真正随机的值。例如,他们可能会查看不同电容器在主板上放电需要多长时间,或者考虑来自时钟的计时信息,或者查看用户如何与键盘交互等。这些数据可以输入到称为一个熵累加器,它慢慢地建立越来越多的随机位。如果您需要一个真正随机且无法提前预测的值,您可以检查您的特定操作系统以了解用于从熵累加器获取数据的机制。/dev/random 例如,在 UNIX 风格的机器上。)

通常,从熵累加器中提取数据需要时间,因为计算机必须等待足够长的时间才能让足够多的不同来源混合在一起才能为您提供高质量的随机数据。因此,一个常见的策略是使用熵累加器来获得高质量的随机种子,然后通过将其用作强伪随机生成器的种子来“拉伸”随机性。

  • @Kaiyaha,依赖(伪)随机数的应用程序很少只需要一个。您可以通过多次调用“rand()”(仅播种一次后)获得此类数字的序列。 (4认同)
  • @Kaiyaha,生成器的周期不需要与“RAND_MAX”相同。它可以很容易地更大或更小。C 语言规范对此没有提出任何要求。如果您对 PRNG 的属性有特定要求,那么建议您选择或编写一个您知道其属性的实现。 (2认同)
  • “RAND_MAX”只是可以生成的最大值。数字序列由数学函数生成。再次调用该函数,您将获得序列中的下一个值。您可以根据需要多次调用此函数,但如上所述,它最终可能会达到重复该模式的程度。 (2认同)