There are several different ways of generating random values in Node.js (JavaScript). Some methods use only base JavaScript functions (e.g. Math.random()) whereas others require additional modules. Generated values also differ from method to method. Some may return only numbers whereas others return base64 string or universally unique identifiers (UUID).

1. Generate random number using Math.random()

The easiest way is to generate numbers using Math.random(). That function returns a floating-point, pseudo-random number that is from 0 (inclusive) up to 1 (exclusive) ([0, 1)). It is also supported by most of the currently available browsers if you need random numbers generation functionality in a browser.

Note that Math.random() returns pseudo-random number. The pseudo-random number appears to be random but it is not. In order to increase "randomness" of that number, the random generator is seeded from the current time.

If you would like to get random numbers generated in a specific range (e.g. [low, high)) you would need to scale generated number to your desired range.

A few examples of scaling generated number to your desired range:

This function generates floating-point between two numbers low (inclusive) and high (exclusive) ([low, high))

function random (low, high) {
    return Math.random() * (high - low) + low;
}

This function generates random integer between two numbers low (inclusive) and high (exclusive) ([low, high))

function randomInt (low, high) {
    return Math.floor(Math.random() * (high - low) + low);
}

This function generates random integer between two numbers low (inclusive) and high (inclusive) ([low, high])

function randomIntInc (low, high) {
    return Math.floor(Math.random() * (high - low + 1) + low);
}

Let's create an array and populate it with random numbers from range: [1, 10].

var numbers = new Array(10);
for (var i = 0; i < numbers.length; i++) {
    numbers[i] = randomIntInc(1,10)
}

It will give something like:

[ 4, 6, 9, 9, 9, 8, 4, 1, 10, 1 ]

Sometimes a single number is not enough and you would need a number composed of exactly certain amount of digits. Note that generated values will be JavaScript strings, not numbers. In that case you can perform modifications of generated values with another function e.g. padding function.

Below there is an example of a left padding function. You can find many more examples also on Internet e.g. pad, lpad, rpad etc. from underscore.string.

function leftPad (str, length) {
    str = str == null ? '' : String(str);
    length = ~~length;
    pad = '';
    padLength = length - str.length;

    while(padLength--) {
        pad += '0';
    }

    return pad + str;
}

Let's perform padding transformation with leftPad function with padding length set to 3.

var numbers = new Array(10);
for (var i = 0; i < numbers.length; i++) {
    numbers[i] = leftPad(randomIntInc(1,10), 3);
}

// output
[ '007', '006', '009', '010', '002', '005', '003', '006', '004', '009' ]

Alternative to padding function might be number conversion to string using different base e.g. base 2 for binary representation of base 16 for hexadecimal representation.

...
    numbers[i] = randomIntInc(1, 10).toString(2); // base 2 - binary format
...

A few output examples:

// output - base 2 - binary format
[ '10001', '110', '11101', '11110', '10', 
  '1111', '100000', '1000000', '1110', '1001' ]

// output - base 8 - octal format
[ '21', '6', '35', '36', '2', '17', '40', '100', '16', '11' ]

// output - base 16 - hexadecimal format
[ '11', '6', '1d', '1e', '2', 'f', '20', '40', 'e', '9' ]

2. Generate universally unique identifiers (UUID)

Another option to generate random values is to use universally unique identifier (UUID) version 4 for that purpose (RFC4122).

UUID is a 128-bit number. Algorithm generating UUID version 4 relies only on random or pseudo-random numbers. It sets only six bits (four version number bits to '0100' and two reserved bits to '01') whereas all remaining 122 bits are random / pseudo-random.

UUID version 4 have to form as follows:

xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx

where x is any hexadecimal digit and y is one of 8, 9, A, or B (e.g., efe1f2aa-1e99-40f2-83fa-8519acd8c34c).

There are several Node.js modules generating UUID numbers. The one which I use very often is node-uuid. Simple and fast implementation of RFC4122 (v1 and v4) UUIDs.

node-uuid module is very simple to use. You can install it using npm manager:

npm install node-uuid

And use it in your script e.g.:

var uuid = require('node-uuid');

var uuid1 = uuid.v4(); // e.g. 32a4fbed-676d-47f9-a321-cb2f267e2918
var uuid2 = uuid.v4(); // e.g. 8b68cf5b-d619-4281-b560-1578b0ee891d

Node that this module uses Math.random() as a base random generator and therefore it can also be used as a library in your browser.

3. Generate random values using Node.js crypto module

Alternative to the above mentioned options might be generation of random values using crypto.randomBytes(size, [callback]) method from crypto Node.js module. randomBytes returns a buffer with randomly generated bytes. It can work asynchronously (when callback function is provided) or synchronously (only size parameter is provided). Returned buffer can be transformed using different encodings to get required format.

Some examples of generating random values in different string formats.

Random value in hex format

In hexadecimal format a single byte generates two characters. So there is no point to generate the same number of bytes as number of output characters. We can only generate half of the bytes.

var crypto = require('crypto');

function randomValueHex (len) {
    return crypto.randomBytes(Math.ceil(len/2))
        .toString('hex') // convert to hexadecimal format
        .slice(0,len);   // return required number of characters
}

var value1 = randomValueHex(12) // value 'd5be8583137b'
var value2 = randomValueHex(2)  // value 'd9'
var value3 = randomValueHex(7)  // value 'ad0fc8c'

Random values in base64 format

In base64 format, the number of output bytes per input byte is 4/3 (33% overhead). So in order to get X output characters we need to generate 3/4 of X bytes. A string in base64 format is composed from the characters as follows: a-z, A-Z, 0-9, + and /. Sometimes '+' and '/' characters are not allowed in the output string. We can replace those two characters after conversion to base64 format.

var crypto = require('crypto');

function randomValueBase64 (len) {
    return crypto.randomBytes(Math.ceil(len * 3 / 4))
        .toString('base64')   // convert to base64 format
        .slice(0, len)        // return required number of characters
        .replace(/\+/g, '0')  // replace '+' with '0'
        .replace(/\//g, '0'); // replace '/' with '0'
}

var value1 = randomValueBase64(12) // value 'wNm2OQu7UaTB'
var value2 = randomValueBase64(2)  // value 'Lj'
var value3 = randomValueBase64(7)  // value 'jWHSOzk'

Random values formatted with biguint-format module

The randomBytes function of crypto module returns a node Buffer with random bytes. A Buffer instance can be very easily converted to string (supports several formats e.g. decimal, binary etc.) using node biguint-format module. Note that the module can format arbitrary length unsigned integer. So you can generates numbers above limits of JavaScript IEEE 754 double-precision floats.

Some examples:

var crypto = require('crypto'),
    biguint = require('biguint-format');

function random (qty) {
    return crypto.randomBytes(qty);
}

console.log(biguint.format(random(8), 'dec'));
// result "6848583289632568793"

console.log(biguint.format(random(8), 'hex', { prefix: '0x' }));
// result "0xd8765863a5bbdc3"

console.log(biguint.format(random(16), 'hex', { prefix: '0x' }));
// result "0x684c3d299c9f15573ea9b93987ca4400"

console.log(biguint.format(random(6), 'bin', { groupsize: 4 }));
// result "1001 1110 1001 0010 0000 0111 0011 1000 1000 1110 0111 0011"

You can read more about biguint-format module on its wiki page.

Random values from limited set of characters

Sometimes there is a need to generate a random value from a limited set of characters e.g. only lowercase characters or odd digits (1,3,5,7,9). As in the previous example, to implement that functionality we can use node crypto module.

Function below generates a specific number of characters from a given set. If a set of characters has not been provided, it will use all numbers and lowercase and uppercase characters.

var crypto = require('crypto');

function random (howMany, chars) {
    chars = chars 
        || "abcdefghijklmnopqrstuwxyzABCDEFGHIJKLMNOPQRSTUWXYZ0123456789";
    var rnd = crypto.randomBytes(howMany)
        , value = new Array(howMany)
        , len = chars.length;

    for (var i = 0; i < howMany; i++) {
        value[i] = chars[rnd[i] % len]
    };

    return value.join('');
}

And the below function executions returns output like:

random(10);         // returns "rkp6rt7EBc"
random(10, "ABBB"); // returns "BABBBBABAB"

Note that the function will use only first 256 characters as numbers generated by the randomBytes function have values from 0 to 255. Also in order to increase probability of a specific characters in the output, you have to add more of those characters in the input set e.g. character set as follows: ABBB will have probabilities of letters: A - 25% and B - 75%.

Conclusion

In this post, I shared with you several different methods to generate random values in Node.js. Some of them might be very good to solve certain type of problem and completely useless for different type of problems.

Every time you have a dilemma which method will work for you, think about allowed output characters (can it have only numbers or letters and numbers), change of having duplicates (e.g. 128-bit UUID values are "very unique") and method "expandability" (e.g. UUID have defined format which can't be changed that easily, whereas random values generated with crypto.randomBytes can be transformed to different formats). That should help you to select "right" method for your needs.

See also