Math.random 产生多少熵?

Aad*_*hah 5 javascript random precision

我想生成一个非常大的随机数。我不需要这个数字是加密安全的。因此,我没有使用crypto.getRandomValues. 目前,我生成的随机数如下:

const random = length =>
    Math.floor(length * Math.random());

const padding = (length, character, string) =>
    (new Array(length + 1).join(character) + string).slice(string.length);

const randomBits = bits =>
    padding(bits, '0', random(Math.pow(2, bits)).toString(2));

const getRandom = bits =>
    bits <= 32 ? randomBits(bits) : randomBits(32) + getRandom(bits - 32);

console.log('         1         2         3         4         5         6');
console.log(getRandom(64));
Run Code Online (Sandbox Code Playgroud)

然而,这似乎有点浪费,因为 JavaScript 中的数字是64 位长的

IEEE 754 双精度二进制浮点格式:binary64

在我看来,我们至少应该能够恢复尾数的所有 52 位。我们可以从Math.randomJavaScript生成的数字中提取多少位熵,以及如何提取?

Pet*_* O. 1

确定性算法(包括伪随机数生成器)本身无法生成熵;它必须来自外部,例如算法接收的种子。

但请注意,ECMAScript 规范Math.random()允许实现使用任何“依赖于实现的算法或策略”,不一定是确定性算法,只要数字是“随机或伪随机选择的,在区间内近似均匀分布” [0, 1)。因此,是否Math.random()实际使用熵同样取决于实现 - 也没有强制要求收集熵来为 PRNG 提供种子的特定策略(如果实现使用)。