Javascript: Generate a random number within a range using crypto.getRandomValues
cryptography, javascript, random, range
Solution
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);
}
Problem
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: - 231 with `Uint8Array(1)` - 54328 with `Uint16Array(1)` - 355282741 with `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