パッケージの詳細

number-generator

MartinHelmut9.4kMIT4.0.6

Generate repeatable pseudo random numbers and non-cryptographic hash numbers for usage in Node.js and browser environments.

numbers, random, alea, murmur

readme

Number Generator

npm Build Status Coverage Status Commitizen friendly Standard Version styled with prettier

Generate repeatable pseudo random numbers and non-cryptographic hash numbers for usage in Node.js (>= 8) and browser environments (major browsers and IE >= 10).

Contents


Update to version 4

  • Change murmurHash to murmurhash2_x86_32 (same function since v2, alias now removed).
  • Non ASCII characters (e.g. chinese or emoji) are now handled properly. This can produce different results if these characters where used before inside an input hash for all murmur hash functions.

Usage

This library (7.55 KB, gzipped size: 2.84 KB) contains the following methods: one PRNG (pseudo random number generator) called Alea and four number hash generators, MurmurHash2 and MurmurHash3 for 32 and 128 bit (x86 and x64) hash strings.

More about the hash function MurmurHash can be found here on wikipedia.

Install

Based on your package manager you can install it via:

# NPM
npm install number-generator

# Yarn
yarn add number-generator

# pnpm
pnpm add 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 as single functions:

// 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";
import murmurhash3_x86_128 from "number-generator/lib/murmurhash3_x86_128";
import murmurhash3_x64_128 from "number-generator/lib/murmurhash3_x64_128";

// 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");
const murmurhash3_x86_128 = require("number-generator/lib/murmurhash3_x86_128");
const murmurhash3_x64_128 = require("number-generator/lib/murmurhash3_x64_128");

Also the library can safely be tree shaked. If tree shaking is used in e.g. Rollup or Webpack this will only put the used function with helpers in your bundle:

import { aleaRNGFactory } from "number-generator";

For use with TypeScript take a look at the usage with typescript section of this document.

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.

Random numbers

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.

⚠️ Attention: The default seed 1 should not be used! It produces one duplicate at 4370 calls. This can be avoided by using a seed larger or equal to 2. Nevertheless, this is still included in the library to not break applications using the default behavior.

Create a new random number generator

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:

const aleaRNGFactory = require("number-generator/lib/aleaRNGFactory");

Now you can create a new generator by calling the function with a seed equal or larger to 2. The number 0, float or negative numbers are not valid and will throw a TypeError. See the remark at the beginning of this section on why to avoid 1 as a seed.

// Valid:
const generator1 = aleaRNGFactory(2);
const generator2 = aleaRNGFactory(4836325);

// Invalid:
const notValidGen1 = aleaRNGFactory(0);
const notValidGen2 = aleaRNGFactory(0.47);
const notValidGen3 = aleaRNGFactory(-1);

Create an unsigned integer

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 will create the exact same result on your machine! You will always get the same value for the same seed.

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

Create an unsigned float

The same that works for the uInt32 method applies to the uFloat32 method, but this time you get an unsigned float.

const { uFloat32 } = aleaRNGFactory(5);
uFloat32(); // 0.0024349885061383247
uFloat32(); // 0.1826920467428863

Again, this will 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

Change the seed

You can change the seed used by the generator object with the setSeed method.

const generator = aleaRNGFactory(2);

// Get some random numbers
generator.uInt32();
generator.uInt32();

// Change seed
generator.setSeed(3);

// Get some more random numbers
generator.uInt32();
generator.uInt32();

Get and restore the state

You can get and restore the internal state with getState and setState.

const generator = aleaRNGFactory(42);
generator.uInt32();
generator.uInt32();
const state = generator.getState(); // Get the generator state
const value1 = generator.uInt32();
generator.uInt32();
generator.uInt32();
generator.setState(state); // Restore the previous state
const value2 = generator.uInt32();

value1 === value2; // true

For TypeScript the state interface is NumberGeneratorState.

import { aleaRNGFactory, NumberGeneratorState } from "number-generator";

const generator = aleaRNGFactory(2);
generator.uInt32();

const state: NumberGeneratorState = generator.getState();

You can set the state with setState on two ways. Either you don't pass any parameter to the state function, where it will reset the state to the initial state. Or you can pass a state object to restore a previous state:

const generator = aleaRNGFactory(2);
generator.uInt32();

const state = generator.getState();
generator.setState(); // Reset the state
generator.uInt32(); // Get a new value

generator.setState(state); // Restore saved state

Something like Math.random?

If you want something similar to Math.random() (without generating duplicated values) you can use the JavaScript Date API with a timestamp and combine it with the uFloat32 method from the aleaRNGFactory e.g.:

const { uFloat32: random } = aleaRNGFactory(Date.now());

// Get a random float number
random();

Murmur hash

To generate a hash there are four functions, murmurhash2_x86_32, murmurhash3_x86_32, murmurhash3_x86_128 and murmurhash3_x64_128. The "murmur hash" functions implement the MurmurHash algorithm for 32 and 128 bit in JavaScript (murmurhash2 and 3) for x86 and x64. They take a string and generate a non-cryptographic hash number as unsigned integer with 32 bit or a string hash with 128 bit.

You can import the functions directly:

const murmurhash2_x86_32 = require("number-generator/lib/murmurhash2_x86_32");
const murmurhash3_x86_32 = require("number-generator/lib/murmurhash3_x86_32");
const murmurhash3_x86_128 = require("number-generator/lib/murmurhash3_x86_128");
const murmurhash3_x64_128 = require("number-generator/lib/murmurhash3_x64_128");

Both murmurhash2_x86_32 and murmurhash3_x86_32 will generate a unsigned 32 bit number. The murmurhash3_x86_128 and murmurhash3_x64_128 functions will generate a 128 bit string. To showcase the difference:

murmurhash2_x86_32("Hello"); // 1826530862
murmurhash3_x86_32("Hello"); // 316307400
murmurhash3_x86_128("Hello"); // "2360ae465e6336c6ad45b3f4ad45b3f4"
murmurhash3_x64_128("Hello"); // "35b974ff55d4c41ca000eacf29125544"

Basic hash generation

All murmur hash functions work the same. So the following examples will take the murmur hash 2 function to demonstrate the usage. To use it pass 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 will create the exact same result on your machine!

Hash based on different seeds

Different seeds generate different results for the same input string. Only whole numbers are valid seeds 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 throws a TypeError:

const hash = murmurhash2_x86_32("My string.", 0.7); // TypeError!

TypeScript

This package contains all the type definitions for TypeScript. 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(2);
// const factory: () => NumberGenerator = aleaRNGFactory;

const hashFn1: NumberHashGenerator = murmurhash2_x86_32;
const hashFn2: NumberHashGenerator = murmurhash3_x86_32;

generator.uInt32();
hashFn1("What?", 42);
hashFn2("something", 14);

Support

This library was tested on the following environments:

  • Node >= 8
  • All major browsers and IE >= 10

Benchmarks

Disclaimer: The following benchmarks were created on a MacBook Pro, Processor 2,7 GHz Intel Core i5 with 8 GB 1867 MHz DDR3 memory and run under Node v14.15.1.

aleaRNGFactory

Comparison between uInt32 and uFloat32 methods:

// v4.0.1
aleaRNGFactory#uInt32()   x 23,094,220 ops/sec
aleaRNGFactory#uFloat32() x 20,571,821 ops/sec

murmurhash

Comparison between murmurhash2_x86_32, murmurhash3_x86_32, murmurhash3_x86_128 and murmurhash3_x64_128 function:

// v4.0.1
murmurhash2_x86_32  x 834,241 ops/sec
murmurhash3_x86_32  x 827,462 ops/sec
murmurhash3_x86_128 x 300,153 ops/sec
murmurhash3_x64_128 x 188,581 ops/sec

To run them on your machine execute pnpm run test:benchmark.

Development

Do you want to contribute have a look at CONTRIBUTING.md

Disclaimer

"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.

Resources used to test against implementations in other languages are:

Big thanks as well to Alex Ciminian for raising the issue with non ASCII characters: https://cimi.io/murmurhash3js-revisited/

更新履歴

Changelog

All notable changes to this project will be documented in this file. See standard-version for commit guidelines.

4.0.6 (2022-08-08)

4.0.5 (2020-12-26)

4.0.4 (2020-03-19)

Bug Fixes

  • use prepare script in package.json to check for package manager (5d1fd5a), closes #591

4.0.3 (2020-03-19)

Bug Fixes

  • use prepare script in package.json to check for package manager (5d1fd5a), closes #591

4.0.2 (2020-03-07)

4.0.1 (2019-09-26)

Bug Fixes

  • small typo in readme file (3ab6068)

4.0.0 (2019-09-26)

⚠ BREAKING CHANGES

  • This fix will change the resulting numbers generated with murmurhash2_x86_32 or murmurhash3_x86_32 were non regular ASCII characters were used as hash before.

Bug Fixes

  • handle non regular ASCII characters for murmurhash implementation (cb570f1)
  • ignore compiled tests output for prettier and lint (9b477ab)

Features

  • add new function murmurhash3_x64_128 to generate 128 bit hash strings for x64 (efccc27)
  • add new function murmurhash3_x86_128 to generate 128 bit hash strings for x86 (f799f89)
  • use C++ reference code to test implementations (f501d9a), closes #8

3.0.1 (2019-06-21)

3.0.0 (2019-06-21)

Bug Fixes

  • state: Don't use import helpers to resolve smaller compile results (246a751)
  • test: Run tests also on Windows (24e6d3b)
  • travis: Simplyfied test command (1f56366)
  • copy all typings to the distribution folder lib (6fd3ead)
  • deactivate minify step (51dd176)
  • ignore esloint compat option for build script (7d98b8e)
  • murmurhash2_x86_32 do not return 0 for strings length multiply of 4 (ceb8704), closes #78
  • remove bundle size based on security and pipeline issues (480ac94)
  • show esm usage in readme (7f51be3)

Build System

  • lint: Added eslint config to lint js config files (editor only) (b95845a)
  • run tests against production bundles (0d87b11)
  • release: Committing generated artifacts in the release commit (c2c658c)
  • add browserlist option for maintained node versions (48a24a7)
  • Added prettier to format code (1149b1d)
  • clean up browser list environment and browser support (72f3b87)
  • drop support for node 6 and IE9 (e17e5e6)
  • generate package-lock.json (474c415)
  • remove husky and lint-staged (3888ea6)
  • replace closure compiler js with terser (a0ccab3)
  • replaced rollup-plugin-cpy with own version (77e936b)
  • strip uglifyjs of api v2 cli flags (e2a1ba1)
  • use prettier as a pre-commit hook for js and md files (203bdb8)
  • rollup: show correct bundle and gzip size (5a33988)
  • rollup: use clear plugin (5be81fb)
  • rollup: use cpy plugin to copy d.ts files to lib (8cf052d)
  • tcs: Use commonjs as target module type (6c17cf0)
  • use rollup and closure to bundle single functions as well (dc623f3)
  • use rollup to build target bundle (d165be7)

Features

  • state: Added getter and setter for internal state (94907f9)
  • add tree shaking check to production build step (64c38c9)
  • Change implementation from typescript to javascript (809ed99), closes #7
  • Initial beta release (0fea451)
  • new function murmurhash3_x86_32 (9506eab)
  • split methods to single functions (e578e61)
  • throw a TypeError if hash is not a string for murmur functions (0b07d34)
  • use mocha and chai instead of jest (c4a20b8)

refactor

  • rename murmurHash function (23951a8)

Tests

  • alea: Added tests for incomplete state object (6a137fd)
  • add explicit test cases for reference implementations (ab888de)
  • karma: Added test runner for browser tests (52e7e45)
  • add check for compatibility and function name export (25a95f6)
  • add explicit implementation test (fa4450c)
  • add TypeScript typings test (e35138d)
  • add unit tests for helpful error message on murmur functions hash validation (bb55991)
  • add utils tests (4d360ec)
  • Fixed karma browser test runner (cf97d33)
  • increase test loop iteration times 10 (393ebc7)
  • Renamed test cases (0a36768)
  • Run build step before run tests (b507592)
  • scope production test run to functions that get packaged (10c126a)
  • use dedicated istanbul configuration file (4763827)
  • Use jest as test runner (2c055ad), closes #6

BREAKING CHANGES

  • murmurHash function is now murmurhash2_x86_32
  • This changes the language the library is implemented in.

2.3.1 (2019-01-19)

2.3.0 (2018-12-20)

Bug Fixes

  • copy all typings to the distribution folder lib (1e9b41e)

Features

  • throw a TypeError if hash is not a string for murmur functions (d971adc)
  • use mocha and chai instead of jest (6d4c037)

2.2.5 (2018-11-13)

2.2.4 (2018-10-18)

2.2.3 (2018-10-16)

2.2.2 (2018-10-03)

2.2.1 (2018-09-09)

2.2.0 (2018-08-21)

Features

  • add tree shaking check to production build step (bc2aa11)

2.1.7 (2018-08-05)

2.1.6 (2018-07-10)

2.1.5 (2018-05-31)

Bug Fixes

  • murmurhash2_x86_32 do not return 0 for strings length multiply of 4 (90b067e), closes #78

2.1.4 (2018-05-29)

2.1.3 (2018-04-26)

2.1.2 (2018-03-24)

2.1.1 (2018-02-21)

2.1.0 (2018-02-16)

Features

  • new function murmurhash3_x86_32 (dad69c7)

2.0.5 (2018-02-13)

2.0.4 (2018-02-13)

2.0.3 (2018-02-13)

2.0.2 (2018-02-12)

Bug Fixes

  • show esm usage in readme (5603246)

2.0.1 (2018-02-12)

Bug Fixes

2.0.0 (2018-02-12)

Code Refactoring

  • rename murmurHash function (5b93f47)

Features

  • split methods to single functions (75bfdfb)

BREAKING CHANGES

  • murmurHash function is now murmurhash2_x86_32

1.0.4 (2018-02-10)

1.0.3 (2018-02-08)

1.0.2 (2018-01-12)

1.0.1 (2017-11-15)

1.0.0 (2017-11-15)

Features

  • Change implementation from typescript to javascript (75167db), closes #7

BREAKING CHANGES

  • This changes the language the library is implemented in.

0.2.16 (2017-11-03)

0.2.15 (2017-07-04)

0.2.14 (2017-07-04)

0.2.13 (2017-06-08)

0.2.12 (2017-04-26)

0.2.11 (2017-04-15)

0.2.10 (2017-04-04)

0.2.9 (2017-03-24)

0.2.8 (2017-03-07)

0.2.7 (2017-03-03)

0.2.6 (2017-02-24)

0.2.5 (2017-02-08)

0.2.4 (2017-01-24)

Bug Fixes

  • travis: Simplyfied test command (2e4a053)

0.2.3 (2017-01-20)

0.2.2 (2017-01-19)

Bug Fixes

  • test: Run tests also on Windows (e055a01)

0.2.1 (2017-01-17)

Bug Fixes

  • state: Don't use import helpers to resolve smaller compile results (54cabba)

0.2.0 (2017-01-17)

Features

  • state: Added getter and setter for internal state (5b836a3)

0.1.9 (2017-01-12)

0.1.8 (2017-01-12)

0.1.7 (2017-01-12)

0.1.6 (2017-01-12)

0.1.5 (2017-01-11)

0.1.4 (2017-01-11)

0.1.3 (2017-01-11)

0.1.2 (2017-01-11)

0.1.1 (2017-01-11)

0.1.0 (2017-01-11)

Features