# A Bit on Random Numbers in JavaScript

`Math.random()`

is a JavaScript function that outputs a random number in the range `[0, 1)`

(from 0 up to 1, but doesn’t include 1). It’s the main source of randomness in JavaScript.

Although the output looks random, it’s actually not.

## Behind the Scenes

`Math.random()`

uses a **pseudo-random number generator** (PRNG). Those algorithms work completely determined by a initial value called “seed”.

Given a seed, the sequence of random numbers is deterministic.

Every PRNG requires a seed, which *generally* is the current system time in milliseconds. Yeah, simple as that.

Speaking of JavaScript language, the PRNG algorithm to deal with the seed is left up to implementors^{[1]}. The algorithm powering V8’s `Math.random()`

was very poor quality until last year (2015), and implementations between engines were pretty inconsistent.

But the scenario has changed. Currently, JavaScript Engines such as SpiderMonkey, V8, Webkit and Chakra all implements Xorshift128+ algorithm^{[2]}, faster than the previous one.

## Secure Randomness

Although randomness was improved in most JavaScript engines, it isn’t trustworthy as seen that standard PRNGs are highly predictable after a certain period. That’s where Web Crypto API shines!

Web Cryptography API introduces `window.crypto.getRandomValues`

, a cryptographically secure pseudo-random number generator (CSPNG), whose output is impossible or highly improbable to distinguish from a truly random one.

### Example

```
// Array containing two 32-bit integers
const arr = new Int32Array(2)
// Override array integers with random values
const random = crypto.getRandomValues(arr)
for (let i = 0; i < random.length; i++) {
console.log(random[i])
}
```

Of course it comes at a performance cost, so make sure you really need secure random numbers in your program.

## Conclusion

If you need apparent randomness–less and speed, you’d probably better off using `Math.random()`

. If you need high-quality randomness, such as in cryptography applications, hashing or statistics, go for a CSPNG such as `window.crypto.getRandomValues`

instead.

Sources: SpiderMonkey, V8, Webkit, Chakra. ↩︎