Math.random() function has a well-deserved reputation for not generating truly random numbers. (Gasp!)
Modern browsers offer a solution with the
crypto.getRandomValues() function that new code should be using instead.
However, most legacy scripts haven't been - and won't be - updated for the new hotness.
I wanted to improve the behavior of legacy code and looked around for a polyfill of
Math.random() that leveraged
crypto.getRandomValues() to generate output, but didn't find one.
It seemed straightforward to implement, so I created
You can learn more about
math-random-polyfill.js on its GitHub project page which includes the following:
The MDN documentation for Math.random() explicitly warns that return values should not be used for cryptographic purposes. Failing to heed that advice can lead to problems, such as those documented in the article TIFU by using Math.random(). However, there are scenarios - especially involving legacy code - that don't lend themselves to easily replacing
crypto.getRandomValues(). For those scenarios,
math-random-polyfill.jsattempts to provide a more random implementation of
Math.random()to mitigate some of its disadvantages.
math-random-polyfill.jsworks by intercepting calls to
Math.random()and returning the same
0 <= value < 1based on random data provided by
crypto.getRandomValues(). Values returned by
Math.random()should be completely unpredictable and evenly distributed - both of which are true of the random bits returned by
crypto.getRandomValues(). The polyfill maps those values into floating point numbers by using the random bits to create integers distributed evenly across the range
0 <= value < Number.MAX_SAFE_INTEGERthen dividing by
Number.MAX_SAFE_INTEGER + 1. This maintains the greatest amount of randomness and precision during the transfer from the integer domain to the floating point domain.
I've included a set of unit tests meant to detect the kinds of mistakes that would compromise the usefulness of
The test suite passes on the five (most popular) browsers I tried, which leads me to be cautiously optimistic about the validity and viability of this approach. :)