UNPKG

randomize-any

Version:

A secure randomization utility library that provides various randomization functions, supporting both browser and Node.js environments.

106 lines (92 loc) 3.02 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var _mapInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/map'); var _reduceInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/reduce'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var _mapInstanceProperty__default = /*#__PURE__*/_interopDefaultLegacy(_mapInstanceProperty); var _reduceInstanceProperty__default = /*#__PURE__*/_interopDefaultLegacy(_reduceInstanceProperty); /** * Randomize an element from an array * @param list array * @returns randomized element */ function randomizeAny(list) { var targetIndex = getSecureWeightedRandom(_mapInstanceProperty__default['default'](list).call(list, () => 1)); return list[targetIndex]; } /** * Randomize an integer * @param min minimum value * @param max maximum value * @returns randomized integer */ function randomizeInteger(min, max) { var list = generateArray(min, max); return randomizeAny(list); } /** * Randomize a float number * @param min minimum value * @param max maximum value * @returns randomized float number */ function randomizeFloat(min, max) { var list = generateArray(min, max, 0.01); return randomizeAny(list); } /** * Get a secure weighted random number * @param weights weight array * @returns randomized index */ function getSecureWeightedRandom(weights) { var sum = _reduceInstanceProperty__default['default'](weights).call(weights, (acc, val) => acc + val, 0); // Calculate total weight // Generate a secure random number (range 0 ~ sum-1) var array = new Uint32Array(1); window.crypto.getRandomValues(array); var rand = array[0] / (0xFFFFFFFF + 1) * sum; // Normalize to [0, sum) // Iterate through weight array to find corresponding random index var cumulative = 0; for (var i = 0; i < weights.length; i++) { cumulative += weights[i]; if (rand < cumulative) { return i; } } return getWeightedRandom(weights); } /** * Get a weighted random number * @param weights weight array * @returns randomized index */ function getWeightedRandom(weights) { var total = _reduceInstanceProperty__default['default'](weights).call(weights, (acc, curr) => acc + curr, 0); var random = Math.random() * total; var sum = 0; for (var i = 0; i < weights.length; i++) { sum += weights[i]; if (random < sum) { return i; } } } /** * Generate an array * @param min minimum value * @param max maximum value * @param step step size * @returns array */ function generateArray(min, max) { var step = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1; var array = []; for (var i = min; i <= max; i += step) { array.push(i); } return array; } exports.getSecureWeightedRandom = getSecureWeightedRandom; exports.randomizeAny = randomizeAny; exports.randomizeFloat = randomizeFloat; exports.randomizeInteger = randomizeInteger;