UNPKG

dtl-js

Version:

Data Transformation Language - JSON templates and data transformation

79 lines (66 loc) 2.59 kB
/* ================================================= * Copyright (c) 2015-2024 Jay Kuri * * This file is part of DTL. * * DTL is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * DTL is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with DTL; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * ================================================= */ // This module provides crypto-compatible randomness let our_crypto; if (typeof window === 'undefined' && typeof crypto === 'undefined') { our_crypto = require('crypto').webcrypto; } else { our_crypto = crypto; } const getRandomValues = our_crypto.getRandomValues.bind(our_crypto); // note that a Uint8Array is not strictly an Array // if you need to push/pop/shift, etc. You should // use Array.from() on the return value of random_bytes. function random_bytes(len) { let byte_array = new Uint8Array(len); getRandomValues(byte_array); return byte_array; } function random_number_up_to(max) { let result; let value_array = new Uint32Array(1); // this looks odd, but is necessary to remove bias that creeps in // when our random value is greater than the maximum multiple of max. // This cleans that up. const max_acceptable_value = Math.floor((0xFFFFFFFF + 1) / max) * max - 1; do { getRandomValues(value_array); result = value_array[0]; } while (result > max_acceptable_value); return result % max; } function random_float() { const array = new Uint32Array(2); getRandomValues(array); // Use bitwise operations to combine the two 32-bit integers const high = array[0] & 0x1FFFFF; // 21 bits for high part (keeping within 53 bits) const low = array[1]; const combined = (high * 2 ** 32) + low; // Normalize to a floating-point number between 0 and 1 const float = combined / 2 ** 53; return float; } let random_stuff = { "random_number_up_to": random_number_up_to, "random_bytes": random_bytes, "random_float": random_float }; module.exports = random_stuff;