xethya-random-bbs
Version:
An implementation of the Blum Blum Shub PRNG.
104 lines (90 loc) • 2.42 kB
JavaScript
/**
* xethya-random-bbs
*
* Copyright © 2016 Joel A. Villarreal Bertoldi. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE.txt file in the root directory of this source tree.
*/
/**
* Default constant value for setting up the BBS PRNG.
* P must be a prime number.
* @type {Number}
*/
const P = 87566873;
/**
* Default constant value for setting up the BBS PRNG.
* Q must be a prime number.
* @type {Number}
*/
const Q = 5631179;
/**
* A list of default seed values, tested to be evenly distributed.
* @see http://wiki.fib.upc.es/sim/index.php/Blum_Blum_Shub#Tests
* @type {Array.<Number>}
*/
const DefaultSeeds = [193945, 740191, 191];
/**
* Instantiates a Blum Blum Shub PRNG.
*/
class BlumBlumShub {
/**
* Initializes the generator.
*
* @param {Number} p A prime value (defaults to P).
* @param {Number} q A prime value (defaults to Q).
* @param {Number} seedNumber A seed number to feed the generator (defaults to any value
* in DefaultSeeds).
* @constructor
*/
constructor(settings) {
const defaults = {
p: P,
q: Q,
seedNumber: null,
};
this.settings = Object.assign({}, defaults, settings);
let seedNumber = this.settings.seedNumber;
const { p, q } = this.settings;
if (seedNumber) {
seedNumber = Math.abs(seedNumber);
} else {
seedNumber = DefaultSeeds[Math.floor(Math.random() * (DefaultSeeds.length))];
}
this.seedNumber = seedNumber;
this.randomIndex = seedNumber;
this.M = p * q;
this.P = p;
this.Q = q;
}
/**
* Determines if the generator works better by being reinstantiated after
* every generated number.
*
* @return {Boolean}
* @static
*/
static recommendsToReinstantiate() {
return false;
}
/**
* Generates a pseudo-random number and updates the seed for a next roll.
* Number is always between 0 and 1.
*
* @return {Number}
*/
generateRandom() {
const r = this.randomIndex * this.randomIndex % this.M;
this.randomIndex = r;
return Math.abs(r / this.M);
}
/**
* Same as `generateRandom()`, but converts the number to an Integer.
*
* @return {Number}
*/
generateRandomInteger() {
return Number(this.generateRandom().toString().replace(/\./, ''));
}
}
export { P, Q, DefaultSeeds, BlumBlumShub };