javascript中的Math.random是如何实现随机性的?

IT技术 javascript random
2021-03-21 12:41:58

javascript中的Math.random是如何实现随机性的?我做了一些随机选择大约 50 个不同选项的东西。我想知道使用 Math.random 来获得随机性应该有多舒服。

5个回答

从规格来看:

随机的():

返回一个带有正号的数字值,大于或等于 0 但小于 1,使用依赖于实现的算法或策略随机或伪随机选择,在该范围内具有近似均匀的分布。这个函数没有参数。

所以答案是这取决于您使用的 JavaScript 引擎。

我不确定是否所有浏览器都使用相同的策略,或者不幸的是该策略是什么

对你的目的来说应该没问题。只有当你做大量的数字时,你才会开始看到一个模式

它足以满足日常需求,这就是 Javascript 的Math.random()用途。没关系。
2021-04-28 12:41:58
@Bob 这只是关于种子。不是它使用的引擎。
2021-05-10 12:41:58
@JohnFeminella 请定义“日常需求”
2021-05-11 12:41:58
@cocotow 等。我想知道天气与伪随机性好不好?就像我猜它对拉斯维加斯或科学来说不够好,但它是否足以满足日常需求?(我做了一些可以根据可能的决定列表为我做出决定的东西。
2021-05-20 12:41:58
@user877329:如果您想要一个不会用作熵源的随机数(例如,用于加密目的,或者您绝对需要保证随机性的地方,例如在赌场),那Math.random()很好。否则,不要使用它。
2021-05-20 12:41:58

如果您不是集中汇集和使用结果,即用于 OAuth,则使用 Math.random() 很好。

例如,我们的站点使用 Math.random() 生成随机的“nonce”字符串以用于 OAuth。最初的JavaScript 库通过使用 Math.random() 从预先确定的列表中选择一个字符来做到这一点:即

for (var i = 0; i < length; ++i) {
    var rnum = Math.floor(Math.random() * chars.length);
    result += chars.substring(rnum, rnum+1);
}

问题是,用户收到重复的随机数字符串(即使使用 10 个字符长度 - 理论上 ~10^18 个组合),通常在几秒钟之内。我猜这是由于 Math.random() 从时间戳中播种,正如其他海报之一所提到的。

+1 用于描述基于时间戳的播种如何在并发环境中生成重复数字。
2021-04-24 12:41:58

确切的实现当然会因浏览器而有所不同,但它们都使用某种伪随机数生成器。虽然它不是真正随机的,但对于所有一般用途来说肯定足够了。

如果您将随机性用于需要非常好的随机性的东西,例如加密或模拟金钱游戏,那么您应该只担心随机性,但无论如何您都不会使用 Javascript。

它是100% 随机的,足以满足您的目的它是按时间播种的,所以每次运行它,你都会得到不同的结果。

将此粘贴到您的浏览器地址栏中...

javascript:alert(Math.random() * 2 > 1);

然后按 [Enter] 几次......我得到了“真、假、假、真”——足够随机:)

您的代码示例没有显示随机生成器的随机性,因为您引入了偏斜。它会导致比真值更多的假值。一个很小的区别,但仍然是一个例子,说明如何通过错误使用来降低随机性的质量。
2021-04-24 12:41:58
是的……但如果我有 50 个复选框……即使我提供样本也足以解决大卫的问题。
2021-04-27 12:41:58

这有点矫枉过正……但是,我无法抗拒这样做:)

您可以在浏览器地址栏中执行此操作。它生成 0 到 4 之间的随机数,100000 次。并输出每个数字生成的次数以及一个随机数跟随另一个的次数。

我在 Firefox 3.5.2 中执行了这个。所有的数字似乎都差不多——表明没有偏见,也没有明显的数字生成方式。

javascript:
var max = 5;
var transitions = new Array(max);
var frequency = new Array(max);
for (var i = 0; i < max; i++)
{
     transitions[i] = new Array(max);
}
var old = 0, curr = 0;
for (var i = 0; i < 100000; i++)
{
   curr = Math.floor(Math.random()*max);
   if (frequency[curr] === undefined) 
   {
      frequency[curr] = -1;
   }
   frequency[curr] += 1;
   if (transitions[old][curr] === undefined)
   {
      transitions[old][curr] = -1;
   }
   transitions[old][curr] += 1;
   old = curr;
}
alert(frequency);
alert(transitions);
这一点也不矫枉过正——完全不够。查看分布并不能告诉您很多关于熵质量的信息,正如其他人所说,确切的行为取决于实现,因此测试 Firefox 3.5.2 并没有说明一般情况。
2021-04-25 12:41:58