I understand you can generate a random number in JavaScript within a range using this function:
function getRandomInt (min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; }
Courtesy of Ionuț G. Stan here.
What I want to know is if you can generate a better random number in a range using crypto.getRandomValues() instead of Math.random(). I would like to be able to generate a number between 0 and 10 inclusive, or 0 - 1, or even 10 - 5000 inclusive.
You'll note Math.random() produces a number like: 0.8565239671015732.
The getRandomValues API might return something like:
Uint8Array(1)
Uint16Array(1)
Uint32Array(1)
.So how to translate that back to a decimal number so I can keep with the same range algorithm above? Or do I need a new algorithm?
Here's the code I tried but it doesn't work too well.
function getRandomInt(min, max) { // Create byte array and fill with 1 random number var byteArray = new Uint8Array(1); window.crypto.getRandomValues(byteArray); // Convert to decimal var randomNum = '0.' + byteArray[0].toString(); // Get number in range randomNum = Math.floor(randomNum * (max - min + 1)) + min; return randomNum; }
At the low end (range 0 - 1) it returns more 0's than 1's. What's the best way to do it with getRandomValues()?
Many thanks
Javascript creates pseudo-random numbers with the function Math. random() . This function takes no parameters and creates a random decimal number between 0 and 1. The returned value may be 0, but it will never be 1.
getRandomValues() is the only member of the Crypto interface which can be used from an insecure context.
The easiest way is probably by rejection sampling (see http://en.wikipedia.org/wiki/Rejection_sampling). For example, assuming that max - min
is less than 256:
function getRandomInt(min, max) { // Create byte array and fill with 1 random number var byteArray = new Uint8Array(1); window.crypto.getRandomValues(byteArray); var range = max - min + 1; var max_range = 256; if (byteArray[0] >= Math.floor(max_range / range) * range) return getRandomInt(min, max); return min + (byteArray[0] % range); }
IMHO, the easiest way to generate a random number in a [min..max]
range with window.crypto.getRandomValues()
is described here.
An ECMAScript 2015-syntax code, in case the link is TL;TR:
function getRandomIntInclusive(min, max) { const randomBuffer = new Uint32Array(1); window.crypto.getRandomValues(randomBuffer); let randomNumber = randomBuffer[0] / (0xffffffff + 1); min = Math.ceil(min); max = Math.floor(max); return Math.floor(randomNumber * (max - min + 1)) + min; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With