当然不是出于任何实际目的,但我尝试使用Node的crypto模块生成安全的随机浮点数。基本上,以下内容:
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位都已设置。其他一切都是随机的。
答案 0 :(得分:0)
从当前版本的节点可以看出,buffer library的源在第906行指定noAssert
还检查提供的数字是否不是{{ 1}},因此只需指定NaN
即可将noAssert
,Infinity
和NaN
写入缓冲区。