Random behaviour is often required in JavaScript, from drawing stars scattered across the night sky to animating chaotic attractors. But there are many different kinds of randomness, and the type you need will differ depending on the application.
Basic Randomness
The simplest form of randomness is the Math.random()
function built into JavaScript. In the console:
> Math.random()
0.19401081069372594
Math.random()
always returns a floating-point number between 0 and 1.
Because it’s so frequently used, Math.random()
is often placed inside its own function in a script:
function getRandom() {
return Math.random();
}
The problem, of course, is that the function will always create a random number within a very limited range; most of the other code recipes on this page are designed to address this.
Randomness Between Numbers: Min Included, Max Excluded
Extending this functionality requires a little bit of math:
Floating Point
function getRandomFloat(min, max) {
return Math.random() * (max - min) + min;
}
getRandomFloat(11, 101)
> 75.31898734299466
Integer
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
getRandomInt(10, 20)
> 12
Random Integer In Range, Both Min & Max Included
function getRandomInRange(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
getRandomInRange(1, 10)
> 7
Coin Toss (Random True / False)
If you want a simple random 0 or 1 to represent a coin toss:
function coinToss() {
return Math.floor(Math.random() * 2);
}
coinToss();
> 0
If you prefer actual true
and false
values:
function coinToss() {
return (Math.floor(Math.random() * 2) === 0);
}
coinToss();
> true
Or alternatively:
function coinToss() {
Math.random()<.5;
}
coinToss();
Or if you want to associate any other words with the coin sides ( yes / no, heads / tails, etc):
function coinFlip() {
return (Math.floor(Math.random() * 2) === 0) ? "up" : "down";
}
coinToss();
> up
Random With Exclusions
For a limited range of integers: create an array of numbers that you’d like to draw from and select randomly from the array:
var numPool = [ 1, 3, 5, 7, 9, 10 ],
rand = numPool[Math.floor(Math.random() * numPool.length)];
For something a little more dynamic: add an array of the numbers you want to exclude, and an empty array to contain the result of filtering the first array into the second:
var numPool = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
var excludePool = [ 3, 4 ];
var filteredPool = [];
Then loop through the numPool
array, test if the number drawn from the array exists in excludePool
, and place the result in filteredPool
:
for (var i = 0; i < numPool.length; i++) {
if (excludePool.indexOf(numPool[i]) === -1) {
filteredPool.push(numPool[i]);
}
}
Finally, draw a random number from filteredPool
:
var rand = filteredPool[Math.floor(Math.random() * filteredPool.length)];
Random, Non-Repeating
For a small set of numbers: create an array filled with elements, shuffle them randomly, put the results into a new array, then pop
out the shuffled elements one at a time:
var numPool = [ 13, 21, 36, 14, 27, 10 ];
function shuffle(numPool) {
for(var j, x, i = numPool.length; i; j = parseInt(Math.random() * i), x = numPool[--i], numPool[i] = numPool[j], numPool[j] = x);
return numPool;
};
var randomResult = shuffle(numPool);
while( randomResult.length > 0 ) {
console.log( randomResult.pop() );
}
For a larger set of numbers, create and fill the array with random integers, rejecting any that have been previously generated:
var numReserve = []
while (numReserve.length < 12) {
var randomNumber = Math.ceil(Math.random() * 1000);
var found = false;
for (var i = 0; i < numReserve.length; i++) {
if (numReserve[i] === randomNumber){
found = true;
break;
}
}
if (!found) { numReserve[numReserve.length]=randomNumber; }
}
In the code above, numReserve
is filled with 12 random numbers between 0 and 1000; the numbers can then be lifted from the array.
Cryptographic Randomness
None of these methods create numbers with enough randomness for cryptographically secure functions (and arguably, Math.random()
isn’t nearly random enough). For those, we can use the Web Cryptography API by creating a typedArray
:
var cryptoStor = new Uint16Array(8);
(In this case, we’re creating an array with eight different slots that can each contain an unsigned 16-bit integer. Other interger options include Int8Array
, Uint8Array
, int16Array
, Int32Array
and Uint32Array
.
Then, fill the array with random numbers of the defined type:
window.crypto.getRandomValues(cryptoStor);
Showing the collected values in the console:
> [43484, 57947, 46691, 49849, 24272, 11827, 28203, 17423]
The Web Cryptography API has good support in modern browsers, although it is vendor prefixed in some cases.
Image by Philippe Put, used under a Creative Commons license
Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.