【问题标题】:Why is Google Chrome's Math.random number generator not *that* random?为什么 Google Chrome 的 Math.random 数字生成器不是 *that* 随机的?
【发布时间】:2012-03-21 23:44:27
【问题描述】:

我今天在各种浏览器中运行一些单元测试时遇到了一个奇怪的“错误”。在今天之前,我已经在 Firefox 中运行了很多次测试,甚至在 IE 中运行了测试,但显然还没有在 Chrome (v19-dev) 中运行。当我在 Chrome 中运行它们时,它始终未能通过一项测试,因为我计算的两个值不匹配。

当我真正深入了解正在发生的事情时,我意识到问题在于我假设如果我用 100,000 个 Math.random() 值填充一个数组,它们都是唯一的(不会有任何冲突)。原来在 Chrome 中这不是真的。

在 Chrome 中,我始终得到至少 两 对匹配的 100,000 个值。 Firefox 和 IE9 从来没有遇到过冲突。这是我写的一个 jsfiddle,只是为了测试它,它在数组中创建 1M Math.random() 条目:http://jsfiddle.net/pseudosavant/bcduj/

有谁知道为什么用于Math.random 的 Chrome 伪随机数生成器真的不是那个随机的?似乎这可能对曾经使用 Math.random 的任何客户端 js 加密例程产生影响。

【问题讨论】:

  • 重复的存在并不意味着非随机性。 en.wikipedia.org/wiki/Birthday_paradox.
  • 当然,根据定义,伪随机生成器根本不是随机的。
  • @NayukiMinase: Math.random() 生成一个双精度浮点数,但 OP 的相等性测试首先将这些数字转换为字符串,因此除非浏览器决定包含超过 15 个位置在其字符串表示形式中超过小数点后,OP 正在比较的值比 的熵少。
  • @delnan:您误读了链接到的答案。根据该答案,100.0 和 100.1 之间大约有 7,036,874,417,766 个双精度浮点数。在 0.0 和 1.0 之间,大约有 2 的 62 次幂的双精度浮点数。
  • @pseudosavant:你确定吗?我原以为5555555.5555555555555 的字符串化可能包括与5.5555555555555 的字符串化相比相似数量的有效数字,并且小数点后的位数更少。

标签: javascript google-chrome random


【解决方案1】:

显然,V8 only works with 32 bit values 中的 Math.random() (过去甚至没有正确随机化所有这些)。并且使用 32 位,在 2^16 = 65k 个值附近发生冲突的概率达到 50%...

【讨论】:

【解决方案2】:

其他答案已经解释了这个问题。如果您希望在 JavaScript 中更好地生成伪随机数,我建议您从这个页面开始:

http://baagoe.com/en/RandomMusings/javascript/

我将 one of the algorithms on this page 改编为用于在浏览器中生成 UUID 的脚本,并且在我的测试中没有发生冲突。

2013 年 10 月 22 日更新

上面链接的页面不再有效。这是来自 Wayback Machine 的快照链接:

http://web.archive.org/web/20120502223108/http://baagoe.com/en/RandomMusings/javascript/

这是一个包含 Alea.js 的 Node.js 模块的链接:

https://npmjs.org/package/alea

【讨论】:

  • @BrianBallsun-Stanton:确实如此。我添加了指向该页面快照的链接。
  • 废话一个现在也倒了:(
  • @user1544793:找到另一个。
【解决方案3】:

见https://medium.com/@betable/tifu-by-using-math-random-f1c308c4fd9d:

如果我们独立分析第一个子生成器,我们会看到它具有 32 位的内部状态。它不是全周期生成器 — 它的实际周期长度约为 5.9 亿(18,030*2¹⁵-1,数学很棘手,但这里和这里都有解释,或者你可以相信我)。所以我们只能用这个生成器生成最多 5.9 亿个不同的请求标识符。如果它们是随机选择的,那么在仅生成 30,000 个标识符后,将有 50% 的碰撞几率。

【讨论】:

    猜你喜欢
    • 2011-05-21
    • 2019-07-27
    • 1970-01-01
    • 2021-02-07
    • 2010-10-30
    • 1970-01-01
    • 1970-01-01
    • 2021-03-22
    • 2010-11-06
    相关资源
    最近更新 更多