Deterministic random generator powered by MurmurHash3
npm install murmur-randomDeterministic random generator powered by MurmurHash3
``javascript
const murmurRandom = require('murmur-random')
const r = murmurRandom('whatever seed you prefer')
console.log(r.value('static string key', 3, 12)) // behaves like Math.random(), but it's repeatable
console.log(r.value('followed by numbers', 42))
console.log(r.value('as many as you prefer', 1, 1, 2, 3, 5, 8, 13, 21))
console.log(r.value('yes, zero is an option'))
const sub = r.subgen('same key and numbers thing', 420, 69)
console.log(sub.value('static string key', 3, 12)) // now it's a different one because the generator is different
// advanced stuff
console.log(r.util.int(r.value('foo', 2), 5, 7)) // int between 5 and 7
console.log(r.util.from(r.value('bar'), ['you', 'can', 'pick', 'random', 'stuff', 'from', 'arrays']))
const seed = r.seed // array of numbers, this is the actual seed the generator uses
const cloned = murmurRandom.raw(seed) // you can save and restore generators with this technique
`
The random generator of murmurRandom can be constructed with the exported function in two ways:
- murmurRandom(string, length = 4): uses a string seed, and derives the numeric seed from it, where length lets you configure the numeric seed lengthmurmurRandom.raw(number[])
- : uses the numeric seed directly
Both functions return the same kind of random generator, which has the following properties:
- r.value(key, ...params): returns a value computed from a string key and an arbitrary amount of numbersr.subgen(key, ...params)
- : returns another random generator, computing its seed from the same kind of inputsr.util
- : various utility functions, see belowr.seed
- : the numeric seed array (read-only, write is unsupported but technically possible)
The string key is meant to be a static identifier of the value you expect from the generator. Do not use dynamic "key" arguments, they can lead to a memory leak (because keys are cached indefinitely). String literals or constants are recommended. Any dynamic change you need can be included in the numeric arguments following the key.
> Why? It's because murmur-random is optimized for speed. Previously, a very similar deterministic random generator was used in the artgen project, which showed that long strings like encoded JSON aren't sufficiently performant with a hash like murmur3
The random generator has a util object, which is meant to help expand a single random value from 0 to 1 into something more usable. It is meant for murmurRandom, but it can also be combined with any other random generator (and imported as murmur-random/util if the rest of the library is not needed).
The provided utility functions are the following:
- r.util.float(value, min, max): returns a float between the specified boundsr.util.int(value, min, max)
- : returns an int between the specified boundsr.util.from(value, array)
- : returns a random element from an arrayr.util.repeat(value, func, min, max)
- : executes the second argument a random amount of times, between min and max. An index is passed as an argument.r.util.chance(value, probability)
- : returns a boolean that's true with the given probabilityr.util.point(value, min, max, ymin, ymax)
- : returns a point in the {x, y} format between the specified boundsr.util.pick(value, array, amount)
- : picks amount random elements from the array
In all of the utility functions, the first value parameter is a value between 0 and 1, generated by r.value() (or any other generator you prefer).
If a util specifies a min, max pair, you can provide just one value, which will set the bounds between 0 and that. Furthermore, if ymin is not passed, r.util.point() uses the same bounds for y as it did on x.
Pull requests are welcome. As always, be respectful towards each other ~~and maybe run or create tests, as appropriate. It's on npm test`, as usual.~~ (that's a todo)
Special thanks to Gary Court, whose MurmurHash3 implementation powers the project.
murmur-random is available under the MIT license.