UNPKG

bali-component-framework

Version:

This library provides a JavaScript based implementation of the Bali Nebula™ Component Framework.

116 lines (98 loc) 4.15 kB
/************************************************************************ * Copyright (c) Crater Dog Technologies(TM). All Rights Reserved. * ************************************************************************ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * * * This code is free software; you can redistribute it and/or modify it * * under the terms of The MIT License (MIT), as published by the Open * * Source Initiative. (See http://opensource.org/licenses/MIT) * ************************************************************************/ 'use strict'; /** * This class provides cryptographically secure random value generation. */ const crypto = require('crypto'); const Decoder = require('./Decoder').Decoder; // PRIVATE CONSTANTS const MAXIMUM_INTEGER = 4294967296; // unsigned // PUBLIC FUNCTIONS /** * This function returns a new random number generator. * * An optional debug argument may be specified that controls the level of debugging that * should be applied during execution. The allowed levels are as follows: * <pre> * 0: no debugging is applied (this is the default value and has the best performance) * 1: log any exceptions to console.error before throwing them * 2: perform argument validation checks on each call (poor performance) * 3: log interesting arguments, states and results to console.log * </pre> * * @returns {Generator} The new generator. */ const Generator = function(debug) { this.debug = debug || 0; return this; }; Generator.prototype.constructor = Generator; exports.Generator = Generator; /** * This method returns a binary string of the specified size containing * randomly generated bytes. * * @param {Number} numberOfBytes The number of bytes in the desired binary string. * @return {Buffer} A data buffer containing random bytes. */ Generator.prototype.generateBytes = function(numberOfBytes) { try { const buffer = crypto.randomBytes(numberOfBytes); return buffer; } catch (cause) { const exception = Error('There was not enough system entropy to generate random bytes.'); if (debug > 0) console.error(exception); throw exception; } }; /** * This method returns a random integer in the range -2147483648..2147483647. * * @return {Number} The random integer. */ Generator.prototype.generateInteger = function() { const decoder = new Decoder(0, this.debug); const integer = decoder.bytesToInteger(this.generateBytes(4)); return integer; }; /** * This method returns a random index in the range in the range 1..length. * * @param {Number} length The length of the collection being indexed. * @return {Number} The random ordinal index. */ Generator.prototype.generateIndex = function(length) { const randomInteger = (this.generateInteger() + MAXIMUM_INTEGER) % MAXIMUM_INTEGER; // in range 0..MAX const index = (randomInteger % length) + 1; // in range 1..length for ordinal based indexing return index; }; /** * This method returns a random probability in the range in the range 0..1. * * @return {Number} The random probability. */ Generator.prototype.generateProbability = function() { const randomInteger = (this.generateInteger() + MAXIMUM_INTEGER) % MAXIMUM_INTEGER; // in range 0..MAX const probability = randomInteger / MAXIMUM_INTEGER; // in range 0..1 return probability; }; /** * This method returns the result of a weighted coin toss. A probability of * zero will always return false and a probability of one will always return true. * * @param {Number} weight The probability that the toss will return true [0.0..1.0]. * @return {Boolean} The result of the coin toss. */ Generator.prototype.flipCoin = function(weight) { const randomInteger = (this.generateInteger() + MAXIMUM_INTEGER) % MAXIMUM_INTEGER; // in range 0..MAX const toss = randomInteger / (MAXIMUM_INTEGER - 1); // convert to range [0.0..1.0) return toss < weight; // true: [0.0..probability) and false: [probability..1.0] };