繁体   English   中英

JavaScript的Math.random是多么随机?

[英]How random is JavaScript's Math.random?

6年来,我的网站上有一个随机数生成器页面。 很长一段时间,它是Google上“随机数生成器”的第一个或第二个结果,并且已被用于在论坛和博客上决定数十个(如果不是数百个)竞赛和绘图(我知道因为我看到了我的推荐人)网络日志,通常去看看)。

今天有人给我发了电子邮件,告诉我它可能不像我想的那么随机。 她尝试生成非常大的随机数(例如,介于1和10000000000000000000之间),发现它们几乎总是相同的位数。 实际上,我将函数包装在一个循环中,因此我可以生成数千个数字,当然,对于非常大的数字, 变化只有大约2个数量级。

为什么?

这是循环版本,所以你可以自己试试:

http://andrew.hedges.name/experiments/random/randomness.html

它既包括Mozilla开发者网络的直接实现,也包括1997年我从不再存在的网页中删除的一些代码(Paul Houle的“Central Randomizer 1.3”)。 查看源以查看每种方法的工作原理。

我在这里其他地方读过有关Mersenne Twister的文章。 我感兴趣的是为什么JavaScript的内置Math.random函数的结果没有更大的变化。 谢谢!

给定1到100之间的数字。

  • 9有1位数(1-9)
  • 90有2位数(10-99)
  • 1有3位数(100)

给定1到1000之间的数字。

  • 9有1位数
  • 90有2位数
  • 900有3位数
  • 1有4位数

等等。

因此,如果您随机选择一些,那么绝大多数所选数字将具有相同的位数,因为绝大多数可能的值具有相同的位数。

您的结果实际上是预期的。 如果随机数均匀分布在1到10 ^ n的范围内,那么您可能希望大约9/10的数字具有n个数字,并且另外9/100的数字具有n-1个数字。

有不同类型的随机性。 Math.random为您提供统一的数字分布。

如果你想要不同的数量级,我建议使用指数函数来创建所谓的幂律分布

function random_powerlaw(mini, maxi) {
    return Math.ceil(Math.exp(Math.random()*(Math.log(maxi)-Math.log(mini)))*mini)
}

此功能应该为您提供与2位数字和3位数字大致相同的1位数字。

随机数也有其他分布,如正态分布 (也称为高斯分布)。

看起来完全随机给我! (提示:这取决于浏览器。)

就我个人而言,我认为我的实施会更好,尽管我从XKCD中偷走了它,应该始终承认:

function random() {
  return 4; // Chosen by a fair dice throw. Guaranteed to be random.
}

下面的文章解释了主要Web浏览器中的math.random()是如何(不)安全的: “主要浏览器中的临时用户跟踪以及跨域信息泄漏和攻击”,Amid Klein(2008) 它并不比典型的Java或Windows内置PRNG功能更强大。

另一方面,实现时段2 ^ 19937-1的SFMT需要为每个PRNG序列维持2496字节的内部状态。 有些人可能认为这是不可原谅的代价。

如果您使用10000000000000000000之类的数字,那么您将超出Javascript使用的数据类型的准确性。 请注意,生成的所有数字都以“00”结尾。

我在Chaos Game上尝试了JS伪随机数生成器。

我的Sierpiński三角形说它非常随意: 分形

好吧,如果您生成的数字高达1e6,那么您希望所有数字的概率大致相等。 这也意味着你只有十分之一的机会得到一个数字少一个数字。 百分之一的机会减少两位数等等。我怀疑你在使用另一个RNG时会看到很多不同,因为你在数字上有一个统一的分布,而不是它们的对数。

从1到N均匀分布的非随机数具有相同的属性。 请注意(在某种意义上)这是一个精确的问题。 0-99(作为整数)的均匀分布确实有90%的数字具有两位数。 在0-999999上的均匀分布有905个数字有五位数。

任何一组数字(在一些不太严格的条件下)都有密度。 当有人想讨论“随机”数字时,应指定这些数字的密度(如上所述)。常见密度是均匀密度。 还有其他:指数密度,正常密度等。在提出随机数发生器之前,必须选择哪个密度是相关的。 而且,来自一个密度的数字通常可以通过龋齿方式容易地转换为另一个密度。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM