Math.random会重复吗?

时间:2014-11-26 15:23:12

标签: javascript random

对于Math.random的不同JavaScript实现:

抛开记忆和长度问题,以下最终会有一个永远重复的数字序列(例如,它只取决于内部种子,当种子回到它的起始点时,数字会重复)?

sequence = Math.random();
while(true){
    sequence += ', ' + Math.random();
}

每个客户端是否具有相同的重复序列(例如,客户端不将特定于客户端的数据合并到随机数生成过程中)?


我问,因为如果可能的数字序列是一个有限的子集,像generating UUIDs with Math.random这样的事情将有更大的碰撞机会。

5 个答案:

答案 0 :(得分:5)

阅读MDN

  

注意:Math.random()不提供加密安全随机数。不要将它们用于与安全相关的任何事情。改为使用Web Crypto API,更确切地说是window.crypto.getRandomValues()方法。

我认为,碰撞最终是可能的。

答案 1 :(得分:2)

This mdn doc for Math.random()说你不能依靠这是真正的安全。

但是你仍然可以尝试另一种建议的window.crypto.getRandomValues(),但在我写这篇文章时,它仍然是实验性的。

  

实现选择随机数的初始种子   生成算法;它不能被用户选择或重置。

     

注意:Math.random()不提供加密安全随机   数字。不要将它们用于与安全相关的任何事情。使用网络   相反,加密API,更确切地说是   window.crypto.getRandomValues()方法。

答案 2 :(得分:2)

它主要取决于底层系统的种子生成器。如果两个客户端具有相同的确切种子,则序列将最终相同...通常。不同的实现之间可能存在细微差别,但默认情况下依赖于Java中的实现:Dig this SO question for additional info

一般来说,种子是“更好一点”,也就是说比一个时间戳稍微“更随机”。

具体做法是:

Windows上的

V8将使用两个不同的s_rand调用和位算术来获取生成器的种子。如果存在/dev/urandom,则会使用它。 urandom非常好,因为它不仅仅使用unix时间戳而是环境噪音。如果两个选项都不可用,V8将只使用不同的时间戳并以数学方式组合它们。但是,随机数的序列不是直接从Java中提取的,并且可能与FireFox客户端的序列完全相同,因为下一个随机数使用不同的数学公式。

Firefox做的事情非常相似,看起来他们从Java中解除了这个定义。至于种子,它的生成与V8的生成非常相似,当它可用时在s_rand上使用/dev/urandom,当它们都不可用时,使用时间戳回落。

总而言之,这一代是“伪随机”,如果下一个随机数的计算是相同的(Chrome和Firefox略有不同),并且两个序列以相同的精确种子开始,那么当然,这两个客户将拥有完全相同的数字序列。从统计数据来看,这种情况发生的可能性微不足道,但可以想象,它确实可能发生。

挖掘以下来源以获得更深入的统计数据,数学上的善良。

来源:

  1. Firefox implementation of math_random
  2. V8's implementation
  3. Breaking the Java random number generator
  4. Predicting the Seed in JS

答案 3 :(得分:0)

所有随机数发生器都需要种子;否则它们只是一个似乎有点随机但最终会重复的数字列表。 Javascripts Math.Random()不接受种子作为参数,而是依赖于内置的种子生成器。即使它是一个伪随机数生成器,因为没有人能控制种子实际启动的位置,Math.random()不应该有任何可预测的模式。

再次检查http://bocoup.com/weblog/random-numbers/

答案 4 :(得分:-1)

不,虽然计算中的任何内容都不是真正随机的,但用于创建这些“随机”数字的算法会让它看起来像是随机的,所以你永远不会得到重复模式。大多数(我不确定Math.random)随机函数将得到当前时间戳并将其作为其过程的一部分使用,这是在这种情况下您不会重复数据的主要原因之一。