UNPKG

randomize-any

Version:

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

94 lines (84 loc) 2.47 kB
import _mapInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/map'; import _reduceInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/reduce'; /** * Randomize an element from an array * @param list array * @returns randomized element */ function randomizeAny(list) { var targetIndex = getSecureWeightedRandom(_mapInstanceProperty(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(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(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; } export { getSecureWeightedRandom, randomizeAny, randomizeFloat, randomizeInteger };