Forked from paragonie-scott/gist:c7a73fd0f759e451cf07
Last active
June 22, 2021 19:14
-
-
Save earthboundkid/d8c0dc2ca19544c744b15221946de658 to your computer and use it in GitHub Desktop.
Javascript CSPRNG for Integers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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