Last active
August 15, 2025 01:09
-
-
Save agwells/7068d4ce3d94aebcf57bef2993ec5b23 to your computer and use it in GitHub Desktop.
Tiny seedable PRNG in JavaScript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* A lightweight seedable RNG for generating low-quality random numbers. | |
* | |
* I find this mostly useful in testing and Storybook, where I want to | |
* repeatably generate a sequence of random numbers, but I don't need | |
* cryptographically strong randomness. It's only useful in those | |
* circumstances. Otherwise... | |
* | |
* - If it doesn't need to be repeatable, just use JS's native "Math.random()" | |
* - If it needs to be cryptographically strong, import a reliable PRNG package | |
* | |
* This function uses the Lehmer RNG algorithm, which is considered pretty | |
* weak by modern PRNG standards but is fine for low-stakes purposes. | |
* @see https://en.wikipedia.org/wiki/Lehmer_random_number_generator | |
* @see https://github.com/tc39/proposal-seeded-random | |
* @example | |
* | |
* // Seed it. | |
* const rand = seedPseudoRand(10); | |
* | |
* // Generate a random integer between 0 and 99 (inclusive) | |
* const n = rand() % 100; | |
* | |
* // Generate a random float between 0 and 1 (inclusive) | |
* const f = rand() / PSEUDO_RAND_MAX; | |
* | |
* @param {number} [seed=1] A seed for the RNG. Must be a positive integer | |
* greater than 0. (Each RNG seeded with the same integer, will return the same sequence of | |
* random integers.) | |
* @returns {function():number} A function that will return a "random" integer | |
* between 0 and PSEUDO_RAND_MAX (0x7ffffffe), inclusive, each time that it is called. | |
*/ | |
export function seedPseudoRand(seed = 1) { | |
const rand = function pseudoRand() { | |
seed = (seed * 48271) % MODULUS; | |
return seed; | |
}; | |
// With the default seed of 1, the first result is 48271, and it'll be similarly small if | |
// the seed is any small integer. So clear out that first result for nicer-looking results. | |
rand(); | |
return rand; | |
} | |
const MODULUS = 0x7fffffff | |
/** | |
* The largest number the PRNG can return. | |
*/ | |
export const PSEUDO_RAND_MAX = MODULUS - 1; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment