最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Cryptographically secure float - Stack Overflow

programmeradmin1浏览0评论

How do you generate cryptographically secure floats in Javascript?

This should be a plug-in for Math.random, with range (0, 1), but cryptographically secure. Example usage

cryptoFloat.random();
0.8083966837153522

Secure random numbers in javascript? shows how to create a cryptographically secure Uint32Array. Maybe this could be converted to a float somehow?

  • The Mozilla Uint32Array documentation was not totally clear on how to convert from an int.
  • Google was not to the point, either.
  • Float32Array.from(someUintBuf); always gave a whole number.

How do you generate cryptographically secure floats in Javascript?

This should be a plug-in for Math.random, with range (0, 1), but cryptographically secure. Example usage

cryptoFloat.random();
0.8083966837153522

Secure random numbers in javascript? shows how to create a cryptographically secure Uint32Array. Maybe this could be converted to a float somehow?

  • The Mozilla Uint32Array documentation was not totally clear on how to convert from an int.
  • Google was not to the point, either.
  • Float32Array.from(someUintBuf); always gave a whole number.
Share Improve this question edited May 23, 2017 at 12:17 CommunityBot 11 silver badge asked Jan 3, 2016 at 10:47 serv-incserv-inc 38.4k9 gold badges190 silver badges212 bronze badges 4
  • 1 Do you need only to support browsers that support window.crypto? – T.J. Crowder Commented Jan 3, 2016 at 10:52
  • 1 @T.J.Crowder: Actually, for my use case, Firefox would suffice. The more general, the merrier. – serv-inc Commented Jan 3, 2016 at 11:02
  • 2 Just to flag it up at a high-level: JavaScript's floats are 64-bit IEEE-754 numbers (well, you can get a 32-bit one if you want), which means they only have 53 (effective) significant binary digits. That's not enough for nearly any cryptographic purpose. – T.J. Crowder Commented Jan 3, 2016 at 12:01
  • 1 @T.J.Crowder: the warning is definitely right. Yet, for some cases (statistical distributions), it is hopefully enough. – serv-inc Commented Jan 3, 2016 at 13:05
Add a ment  | 

1 Answer 1

Reset to default 10

Since the following code is quite simple and functionally equivalent to the division method, here is the alternate method of altering the bits. (This code is copied and modified from @T.J. Crowder's very helpful answer).

// A buffer with just the right size to convert to Float64
let buffer = new ArrayBuffer(8);

// View it as an Int8Array and fill it with 8 random ints
let ints = new Int8Array(buffer);
window.crypto.getRandomValues(ints);

// Set the sign (ints[7][7]) to 0 and the
// exponent (ints[7][6]-[6][5]) to just the right size 
// (all ones except for the highest bit)
ints[7] = 63;
ints[6] |= 0xf0;

// Now view it as a Float64Array, and read the one float from it
let float = new DataView(buffer).getFloat64(0, true) - 1; 
document.body.innerHTML = "The number is " + float;

Explanation:

The format of a IEEE754 double is 1 sign bit (ints[7][7]), 11 exponent bits (ints[7][6] to ints[6][5]), and the rest as mantissa (which holds the values). The formula to pute is

To set the factor to 1, the exponent needs to be 1023. It has 11 bits, thus the highest-order bit gives 2048. This needs to be set to 0, the other bits to 1.

发布评论

评论列表(0)

  1. 暂无评论