2013-04-19 3 views
0

Не для какой-либо практической цели, конечно, но я попытался создать безопасное случайное число с плавающей запятой, используя модуль crypto узла. По сути, следующее:Node.js Secure Random Float from Crypto Buffer

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 одинарной точности с плавающей запятой спецификации номер, но я не знаком с точно, как поплавок хранится в двоичном виде.

Почему это происходит именно так, и, кроме простого генерирования поплавков, пока я не получу действительное число, как я могу обойти это?

EDIT: при просмотре отфильтрованных двоичных данных, похоже, что все они соответствуют одному и тому же шаблону: все первые 8 бит установлены. Все остальное случайное.

+0

Похоже, что '0x7F800000' - бесконечность, а' 0xFF800000' - -Инфинити. '0b * 11111111', за которым следуют 23 бита, по крайней мере один, если он задан, приводит к' NaN'. – skeggse

ответ

0

Как видно из текущей версии узла, источник обозначает buffer library «s, на линии 906, что noAssert также проверяет, чтобы увидеть, если номер предоставляется не NaN, так просто указав noAssert позволяет написание Infinity, NaN , и -Infinity в буфер.