Skip to content
扫码开始移动端阅读

一文搞懂前端随机数

随机数生成原理

关于随机

计算机无法真正产生绝对的随机数,因为其本质是按照一定规律执行的。然而,我们可以通过一些算法生成具有良好统计特性的“伪随机数”。

伪随机数生成器(PRNG)

PRNG

伪随机数生成器是通过一个初始值(种子)和确定性算法生成一系列看似随机的数。常见的PRNG算法包括线性同余发生器(LCG)和梅森旋转算法等。这些算法通常能够满足一般应用的需求,但在密码学等敏感场景中需要更高质量的随机数。

真随机数生成器(TRNG)

TRNG

真随机数生成器利用物理过程,如电子噪声或光子的不可预测性,产生真正的随机数。硬件随机数生成器通常比软件实现更安全,因为它们不依赖于算法。

js中的随机数

JavaScript 中的随机数通常是通过 Math.random() 函数来生成的。这个函数返回一个范围在 [0, 1) 之间的伪随机浮点数。注意,生成的随机数是左闭右开区间,即包括0,但不包括1。

如何生成随机数(入门)

javascript
const randomInt = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;

生成随机字符串(进阶)

javascript
const randomString = (length) => {
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  let result = '';
  for (let i = 0; i < length; i++) {
    result += chars.charAt(Math.floor(Math.random() * chars.length));
  }
  return result;
};

生成随机中文(高阶)

javascript
// 通过Unicode编码范围来生成随机中文(别真的用。因为大部分都是生僻字)
const randomChinese = (length) => {
  let result = '';
  for (let i = 0; i < length; i++) {
    const random = Math.round(Math.random() * 20901) + 19968;
    result += String.fromCharCode(random);
  }
  return result;
};

浏览器是如何实现Math.random()

V8引擎(Chrome浏览器)

在V8引擎中,Math.random() 的实现基于Mersenne Twister算法。Mersenne Twister是一个高质量的伪随机数生成器,它具有长周期和良好的统计性质。具体的实现可能会使用一些种子和状态来初始化Mersenne Twister,并通过每次调用来生成下一个随机数。这个算法提供了良好的随机性,适用于一般应用。

DANGER

由于JavaScript的规范并没有强制要求具体的随机数生成算法,因此不同浏览器厂商可以选择不同的实现方式。在实际应用中,如果需要更高质量、更安全的随机数,可以考虑使用window.crypto.getRandomValues()方法,它使用浏览器提供的加密强随机数生成器。这个方法返回一个Uint8Array数组,可以转换为其他数据类型。

关于Mersenne Twister

INFO

Mersenne Twister(梅森旋转算法)是一种常用于生成伪随机数的算法,由1997年由日本的数学家松本吾郎(Makoto Matsumoto)和西村康稔(Takuji Nishimura)共同开发。它的名字来源于梅森数(Mersenne primes),这是一类具有特定形式的质数。

特点

  1. 长周期性: Mersenne Twister算法具有非常长的周期,通常为2^19937-1。这意味着在生成的随机数序列中,经过这么多次随机数生成之后,序列会重复。
  2. 良好的统计特性: Mersenne Twister生成的随机数具有良好的统计特性,能够均匀地覆盖整个随机数范围,且能够通过一些统计测试。
  3. 快速且高效: 算法的实现相对简单,运算速度较快,适用于需要大量随机数的应用场景。

总结

Mersenne Twister算法的实现主要基于线性同余法(linear congruential method),但相比于传统的线性同余法,它引入了更复杂的状态更新机制,使得生成的随机数更为均匀分布且不容易出现周期性规律。

关于线性同余法

INFO

线性同余法(Linear Congruential Generator,简称LCG)是一种用于生成伪随机数的算法。它是最简单且最古老的伪随机数生成器之一。线性同余法通过对前一个随机数进行一系列的线性变换和取模运算来生成下一个随机数。

特点

  1. 简单高效: 线性同余法的实现非常简单,只需要一些简单的数学运算即可。同时,它的运算速度也很快,适用于需要大量随机数的应用场景。
  2. 周期性: 线性同余法生成的随机数序列具有周期性,即经过一定次数的随机数生成之后,序列会重复。
  3. 统计特性较差: 线性同余法生成的随机数序列通常不能很好地覆盖整个随机数范围,且容易出现一些规律性的分布。

总结

线性同余法的实现非常简单,但由于其统计特性较差,通常只适用于一些简单的应用场景。

关于window.crypto.getRandomValues()

INFO

window.crypto.getRandomValues()方法用于生成加密强随机数。它接受一个Uint8Array数组作为参数,返回一个填充了随机数的数组。这个方法使用浏览器提供的加密强随机数生成器,生成的随机数具有良好的统计特性,适用于一些对随机数质量要求较高的场景,如密码学。

特点

  1. 高质量: window.crypto.getRandomValues()方法使用浏览器提供的加密强随机数生成器,生成的随机数具有良好的统计特性,适用于一些对随机数质量要求较高的场景,如密码学。
  2. 低效: 由于使用了加密强随机数生成器,因此window.crypto.getRandomValues()方法的运算速度较慢,适用于需要少量随机数的应用场景。

总结

window.crypto.getRandomValues()方法使用浏览器提供的加密强随机数生成器,生成的随机数具有良好的统计特性,适用于一些对随机数质量要求较高的场景,如密码学。