Generate secure random numbers
To generate a random number between 0 and 1, use Math.random()
. But watch out, as it is not guaranteed to be cryptographically secure, and as such, it should not be used when encryption is involved.
Fortunately, there is a new API that provides such functionality. It is the crypto.getRandomValues()
.
But this works differently. You need to pass a typed array, and it fills it with random values.
To get a 32bit random value, use:
window.crypto.getRandomValues(new Uint32Array(1))[0]; // 0 - 4294967295
But it is not the same API Math.random()
provides, and getting a 0 - 1 number is usually easier to work with.
You might be tempted to divide the result by 4294967295, but don't. It provides only 32 bits of randomness, which is suboptimal and might be less than what Math.random()
provides.
To get the full 52 bits of randomness numbers can hold, use the following script:
const random = () => {
// 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;
return float;
}
console.log(random()); // 0 - 1, 52 bits