0

当然,不是出于任何实际目的,但我尝试使用 Node 的加密模块生成一个安全的随机浮点数。本质上,如下:

var crypto = require('crypto');
var buf = crypto.randomBytes(4);
var float = buf.readFloatBE();

就以下测试而言,这在平均 0.40% 的情况下不起作用。我没有得到浮点数,而是得到NaN.

var colors = require('colors');
var crypto = require('crypto');

var buf = new Buffer(4);
var fails = 0, tries = 100000;
var failures = [];

for (var i = 0; i < tries; i++) {
    var num = crypto.randomBytes(4).readFloatBE(0);
    try {
        buf.writeFloatBE(num, 0);
    } catch (e) {
        fails++;
        failures.push(buf.readUInt32BE(0).toString(2));
    }
}

var percent = 100 * fails / tries;
if (fails)
    percent = (percent.toFixed(2) + "%").red;
else
    percent = '0.00%'.blue.bold;
console.log('Test ' + 'complete'.green.bold + ', ' + percent + ": " + fails + " / " + tries);
fails && console.log('Failed'.red + ' values:', failures.join(', '));

我猜这是由于 IEEE 单精度浮点数规范,但我不熟悉浮点数是如何存储为二进制的。

为什么会发生这种情况,确切地说,除了简单地生成浮点数直到我得到一个有效数字之外,我该如何规避这个问题?

编辑:查看过滤后的二进制数据时,它们似乎都遵循相同的模式:前 8 位都已设置。其他一切都是随机的。

4

1 回答 1

0

从当前版本的 node 可以明显看出,缓冲区库的源代码在第 906 行指定,noAssert还检查提供的 Number 是否不是NaN,因此只需指定noAssert允许将InfinityNaN和写入-Infinity缓冲区。

于 2013-04-19T04:48:40.027 回答