Skip to content

A browser-based polyfill for JavaScript's Math.random() that tries to make it more random


Notifications You must be signed in to change notification settings


Folders and files

Last commit message
Last commit date

Latest commit



6 Commits

Repository files navigation


A browser-based polyfill for JavaScript's Math.random() that tries to make it more random

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 Math.random() with crypto.getRandomValues(). For those scenarios, math-random-polyfill.js attempts to provide a more random implementation of Math.random() to mitigate some of its disadvantages.

Important: If at all possible, use crypto.getRandomValues() directly. math-random-polyfill.js tries to improve the security of legacy scripts, but is not a substitute for properly implemented cryptography.


Add math-random-polyfill.js to your project and reference it from a web page just like any other script:

<script src="math-random-polyfill.js"></script>

Do this as early as possible for the broadest impact - some scripts capture Math.random() during initial load and won't benefit if loaded before math-random-polyfill.js.


math-random-polyfill.js works by intercepting calls to Math.random() and returning the same 0 <= value < 1 based 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_INTEGER then 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.

An alternate approach that uses random bits to create floating point numbers directly suffers from the problem that the binary representation of those numbers is non-linear and therefore the resulting values would not be uniformly distributed.

The code and tests for math-random-polyfill.js are implemented in ECMAScript 5 and should work on all browsers that implement crypto.getRandomValues() and Uint32Array.


Tests are known to pass on the following browsers:

  • Chrome
  • Edge
  • Firefox
  • Internet Explorer 11
  • Safari

They may pass on other browsers as well; run the math-random-polyfill.js test suite to check.


A browser-based polyfill for JavaScript's Math.random() that tries to make it more random







No releases published


No packages published