Skip to content

Instantly share code, notes, and snippets.

@earthboundkid
Forked from paragonie-scott/gist:c7a73fd0f759e451cf07
Last active June 22, 2021 19:14
Show Gist options
  • Save earthboundkid/d8c0dc2ca19544c744b15221946de658 to your computer and use it in GitHub Desktop.
Save earthboundkid/d8c0dc2ca19544c744b15221946de658 to your computer and use it in GitHub Desktop.
Javascript CSPRNG for Integers
function secureRand(min, max) {
let range = max - min;
if (range < 2) {
return min;
}
let bits_needed = Math.ceil(Math.log2(range));
if (bits_needed > 31) {
throw new Error("cannot generate numbers larger than 31 bits.");
}
let mask = (1 << bits_needed) - 1;
let start = window.performance.now();
const maxTime = 100; // 100ms
// Create byte array
let byteArray = new Uint32Array(1);
while (true) {
// fill it with random numbers
window.crypto.getRandomValues(byteArray);
let rval = bigEndian(byteArray);
// Use & to apply the mask and reduce the number of lookups
rval = rval & mask;
if (rval < range) {
// Return an integer that falls within the range
return min + rval;
}
// Integer out of acceptable range
if (window.performance.now() - start > maxTime) {
throw new Error("took too long generating random number");
}
}
}
function bigEndian(byteArray) {
return new DataView(byteArray.buffer).getUint32();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment