JavaScript中的Math.random()是最常用的随机数生成方法,但它并不适合所有场景。Math.random()生成的是伪随机数,且不是密码学安全的。本文将介绍如何在JS中生成不同质量要求的随机数,以及各自的适用场景。
一、Math.random()的局限
Math.random()返回0到1之间的浮点数,使用简单。但它基于伪随机数生成器,算法可预测。对于抽奖、游戏等对随机性要求不高的场景够用,但不能用于密码学场景(如生成Token)。此外,Math.random()的分布可能不完全均匀,在某些浏览器实现中有偏差。
二、密码学安全的随机数:Crypto.getRandomValues
现代浏览器提供了Web Crypto API,其中的crypto.getRandomValues()可以生成密码学安全的随机数。它基于操作系统熵源,无法预测。适用于生成会话ID、CSRF Token、API密钥等安全敏感场景。使用方法:const array = new Uint32Array(1); crypto.getRandomValues(array); const randomNumber = array[0];
三、生成指定范围的随机整数
无论是Math.random()还是crypto.getRandomValues(),生成的都是整数随机数。要生成min到max之间的随机整数,可以用公式:Math.floor(Math.random() * (max - min + 1)) + min。对于密码学安全的版本,可以用类似方法,但注意避免模偏差。
四、避免模偏差的技巧
当用随机整数取模来限制范围时,如果随机数的最大值不是范围大小的整数倍,会产生模偏差——某些数字出现的概率略高。对于密码学场景,需要处理这个问题。常用方法是拒绝采样:如果生成的随机数落在最大有效范围之外,就丢弃重新生成。
五、使用一页共享验证随机数分布
打开一页共享的随机数生成器,可以批量生成大量随机数,观察分布是否均匀。比如生成1000个1-100的整数,看看每个数字出现的次数是否接近10次。这可以帮助你验证随机算法的质量。

