Generate repeatable pseudo random numbers and non-cryptographic hash numbers for usage in Node.js and browser environments.
Note on updating from v1 or v2 to v3: It can safely be done 🥳. Compatibility is restored for all versions so that nothing breaks on an major version bump.
This library (2.51 KB, gzipped size: 1.12 KB) contains the following methods: one PRNG (pseudo random number generator) called Alea and two number hash generator, MurmurHash2 and MurmurHash3 for unsigned integer with 32bit. The Alea implementation is originally from Johannes Baagøe. Johannes Baagøe site is offline but here is a Web Archive Link or alternatively a direct mirror of Johannes Baagøe's wiki from Nick Quinlan.
More about the hash function MurmurHash can be found here on wikipedia.
Use NPM to install the package:
npm install --save number-generator
After that you can import it either as a library, e.g.:
// ESM
import * as numberGenerator from "number-generator";
// CJS
const numberGenerator = require("number-generator");
Or the single functions itself:
// ESM
import aleaRNGFactory from "number-generator/lib/aleaRNGFactory";
import murmurhash2_x86_32 from "number-generator/lib/murmurhash2_x86_32";
import murmurhash3_x86_32 from "number-generator/lib/murmurhash3_x86_32";
// CJS
const aleaRNGFactory = require("number-generator/lib/aleaRNGFactory");
const murmurhash2_x86_32 = require("number-generator/lib/murmurhash2_x86_32");
const murmurhash3_x86_32 = require("number-generator/lib/murmurhash3_x86_32");
Also because the library can safely be tree shaked, you can import the functions for ESM like:
// If tree shaking is used in e.g. Rollup or Webpack this
// will only put this function with helpers in your bundle:
import { aleaRNGFactory } from "number-generator";
For use with TypeScript take a look at the usage with typescript section.
Remark: For direct browser usage you can use the exposed numberGenerator
global, e.g.:
// Direct browser usage e.g.:
numberGenerator.murmurhash2_x86_32("something");
All supported environments are listed under the support section.
You can use the aleaRNGFactory
method to generate (pseudo) random numbers based an a seed (default seed is 1
). Every seed produces the same result for the created getter method.
First step is to include the library functions you want to use in your application. If you only want to use the alea implementation you can import it directly by:
const aleaRNGFactory = require("number-generator/lib/aleaRNGFactory");
Now you can create a new generator with the random seed 1
or a custom one as "unsigned integer". The number 0
is not valid and will throw an exception as TypeError
.
// Valid:
const generator1 = aleaRNGFactory(); // Default seed: 1
const generator2 = aleaRNGFactory(4836325);
// Invalid:
const notValidGen1 = aleaRNGFactory(0);
const notValidGen2 = aleaRNGFactory(0.47);
const notValidGen3 = aleaRNGFactory(-1);
If you have a valid generator object you can use the uInt32
method to get a random unsigned integer. Call it multiple times to get new numbers.
const { uInt32 } = aleaRNGFactory(10);
uInt32(); // 20916391
uInt32(); // 1567221093
This should create the exact same result on your machine! You get always the same values for the same seed used.
This means if you create multiple generators with the same seed, you get the same result for the n-th call:
const generator1 = aleaRNGFactory(2);
const generator2 = aleaRNGFactory(2);
const value1 = generator1.uInt32();
const value2 = generator2.uInt32();
value1 === value2; // true
The same that works for the uInt32 method applies to the uFloat32
method. But this time you get an unsigned float value.
const { uFloat32 } = aleaRNGFactory(5);
uFloat32(); // 0.0024349885061383247
uFloat32(); // 0.1826920467428863
Again, this should create the exact same result on your machine!
If you create multiple generators with the same seed, you get the same result for the n-th call:
const generator1 = aleaRNGFactory(4);
const generator2 = aleaRNGFactory(4);
const value1 = generator1.uFloat32();
const value2 = generator2.uFloat32();
value1 === value2; // true
You can change the seed used by the generator object with the setSeed
method.
const generator = aleaRNGFactory(1);
// Get some random numbers
generator.uInt32();
generator.uInt32();
// Change seed
generator.setSeed(2);
// Get some more random numbers
generator.uInt32();
generator.uInt32();
You can get and restore the internal state with getState
and setState
.
const generator = aleaRNGFactory();
generator.uInt32();
generator.uInt32();
const state = generator.getState(); // Get the generator state
const value1 = generator.uInt32();
generator.uInt32();
generator.uInt32();
generator.setState(state); // Set the previouse state
const value2 = generator.uInt32();
value1 === value2; // true
For TypeScript the state interface is NumberGeneratorState
.
const generator = aleaRNGFactory();
generator.uInt32();
const state: NumberGeneratorState = generator.getState();
You can set the state with setState
on two ways, either if you don't pass any parameter to the state function it will reset the state to the initial state. Or you can pass an state to restore a previous setting:
const generator = aleaRNGFactory();
generator.uInt32();
const state = generator.getState();
generator.setState(); // Reset the state
generator.uInt32(); // Get a new value
generator.getState(state); // Restore saved state
If you want something similar to Math.random()
you can use the JavaScript Date API with a timestamp, e.g.:
const { uFloat32: random } = aleaRNGFactory(Date.now());
// Get a random float number
random();
To generate number a hash there are two functions, murmurhash2_x86_32
and murmurhash3_x86_32
. The murmurhash
functions implement the MurmurHash algorithm for 32bit integer in JavaScript (murmurhash2 and 3). They take a string and generates a non-cryptographic hash number as unsigned integer (32bit).
You can import the functions directly by:
const murmurhash2_x86_32 = require("number-generator/lib/murmurhash2_x86_32");
// or
const murmurhash3_x86_32 = require("number-generator/lib/murmurhash3_x86_32");
All murmur hash functions work the same. So the following examples will take the murmur hash 2 function to demonstrate the usage. The simplest way to use it is by passing a string to generate the hash number. The default seed used is 0
.
const hash1 = murmurhash2_x86_32("My string.");
const hash2 = murmurhash2_x86_32("My string.", 0);
hash1; // 1836966117
hash1 === hash2; // true
This should create the exact same result on your machine!
Different seeds generate different results for the same input string. Only whole numbers are valid seed values for any murmur hash function!
const hash1 = murmurhash2_x86_32("My string.", 1);
const hash2 = murmurhash2_x86_32("My string.", 2);
hash1 === hash2; // false
A float number as a seed value throws a TypeError
:
const hash = murmurhash2_x86_32("My string.", 0.7); // TypeError!
To ensure compatibility to v1 of this library the murmurhash2_x86_32
is also exposed as murmurHash
method and can be used by importing it from the library:
const { murmurHash } = require("number-generator");
This package contains all the type definitions for TypeScript needed. Every murmur hash function implements the NumberHashGenerator
interface.
import {
NumberGenerator,
NumberHashGenerator,
aleaRNGFactory,
murmurhash2_x86_32,
murmurhash3_x86_32
} from "number-generator";
const generator: NumberGenerator = aleaRNGFactory();
// const factory: () => NumberGenerator = aleaRNGFactory;
const hashFn1: NumberHashGenerator = murmurhash2_x86_32;
const hashFn2: NumberHashGenerator = murmurhash3_x86_32;
generator.uInt32();
hashFn1("What?", 42);
hashFn2("something", 14);
This library was tested on the following environments:
- Node >= 8
- All major browsers and IE >= 10
Exceptions for Node are versions that reached the End-of-Life as defined under https://github.com/nodejs/Release#end-of-life-releases.
If you want to contribute see the CONTRIBUTING.md
"Why pseudo random number generators and number hash functions" you may ask? Read more in this fantastic blog post about "A primer on repeatable random numbers" from Rune Skovbo Johansen.
Thanks to Johannes Baagøe for the Alea port and Ray Morgan for the MurmurHash2 algorithm implementation in JavaScript. Also thanks to Karan Lyons for the MurmurHash3 implementation.