2017-02-28 66 views
1

每次调用random()方法时,是否需要更改随机种子?需要在调用random()方法时更改随机种子?

或者应该生成一个随机种子,直到重新启动我的程序才能更改?

哪个选择可以得到更好的随机数?

关于我的程序

我发展与Node.js扑克程序。我需要洗牌Math.random()

由于原创原创Math.random()方法不够安全,所以我用seedrandom包重写了它。

我可以提供一个随机种子seedrandom。但是我不知道何时需要更改或需要在程序运行时更改随机种子。

+2

除非您正在制作自己的伪随机生成器,然后种子会在'random()'方法内自动更改。如果种子不变,那么你需要另一个临时变量使种子本身无用 – Spektre

+0

你的目的是什么,你的计划是什么?你应该指出他们继续你的问题。 – HappyHal

+0

我已经添加了一些关于我的程序的消息。谢谢 – sjfkai

回答

0

使用常量随机种子在开发时非常有用 - 它允许您持续的行为,这意味着每次运行程序时都会出现一个bug。

测试时 - 您可以生成随机种子作为参数,如果程序崩溃重新创建错误。

在现实世界的应用程序中,您不能拥有一个常量随机种子,因为它会使整个程序常量为。在你的扑克游戏中,正在处理的牌将永远是相同的,你可以理解这可能是一个问题。对于在每次随机()调用之前生成一个新的种子,伪随机生成器用于创建尽可能真正的随机变量,真随机意味着一旦你得到一个系列,你就不能预测下一个数字以前的数字。所以每次改变种子都没有任何意义。

+0

谢谢。如果我在扑克程序启动时生成随机种子(不是常量,如时间戳)。只有在程序重新启动时才更改种子。会有什么问题吗?换句话说,我能用一个随机种子产生无数的随机数吗? – sjfkai

+0

@sjfkai,如果您使用种子的时间戳,您将无效所有努力找到一个安全的RNG。我对Node.js一无所知,但它看起来像需要用[crypto.randomBytes(256)](https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback)(或[ (https://en.wikipedia.org/wiki/Fisher-Yates#Pseudorandom_generators:_problems_involving_state_space.2C_seeding.2C_and_usage))来洗牌一张52张牌。你可以在同一个加密类中寻找一个可靠的CPRNG。 – sh1

0

所以你问的是随机安全呢?

在这种情况下,它是完全不同的问题。

使用固定伪随机函数作为随机源始终包含输出可能具有可被潜在的黑客/作弊者利用的确定性属性的风险。例如卡一些序列之后,游戏会重复自我等等

有一些事情可以做,以防止或降低这种风险:

  1. 使用随机生成

    这种方式是最安全的,但在大多数情况下不可用,因为您需要一个真正的随机性来源(如天线或某些传感器获取白噪声等),这需要非标准硬件,而大多数机器都不存在这种硬件。

  2. 随机化时不时

    所以一段时间后,经过尝试随机你的后裔(这是你问)。通常使用一些更好的随机变量来提高随机性,如使用实时,等等来衡量人的响应时间(密钥保持多久或平均点击率等)。

    这样您应该更改种子在某些饱和或随机时间段过去之后,可以预测输出的某些属性。

  3. 使用一个以上的伪随机数发生器

    如果你有更多的发电机可以随机时间它们之间进行切换,以时间甚至更低的风险。你也可以用另一台发电机计算一台发电机的种子。

  4. 非恒定的随机调用频率

    如果在每一帧不断随机电话/转什么,然后你有更高的概率,你的应用程序将“饱和”或重复自我。为了降低风险,您可以将随机值加上空的随机呼叫。

检查随机性是使用2D gfx的好主意。您可以轻松检测图案和饱和度,以便估计您应该随机抽出的频率。例如,这样的情节看:

同样采用直方图有助于看到输出的质量。 (定制发生器上的某些种子可能会导致丢失数字或分发缺陷)