UNPKG

js-randomness-predictor

Version:

Predict Math.random output in Node, Deno, Bun, Chrome, Firefox, and Safari

49 lines (48 loc) 2.32 kB
import { SemanticVersion } from "../types.js"; /** * * In Node versions <= 11 the ToDouble method was different : https://github.com/nodejs/node/blob/v10.0.0/deps/v8/src/base/utils/random-number-generator.h#L114-L120 * ``` * static inline double ToDouble(uint64_t state0, uint64_t state1) { * // Exponent for double values for [1.0 .. 2.0) * static const uint64_t kExponentBits = uint64_t{0x3FF0000000000000}; * static const uint64_t kMantissaMask = uint64_t{0x000FFFFFFFFFFFFF}; * uint64_t random = ((state0 + state1) & kMantissaMask) | kExponentBits; * return bit_cast<double>(random) - 1; * } * ``` * * In Node v24.x.x (commit was in Feb2025), V8 updated their impl of the `ToDouble` method. The old method was in use since 2022. * This caused breaking changes to this predictor, so we now have to detect node version so we can choose which ToDouble to implement. * - Old Impl: https://github.com/v8/v8/blob/e99218a1cca470ddec1931547b36a256f3450078/src/base/utils/random-number-generator.h#L111 * ``` * // Static and exposed for external use. * static inline double ToDouble(uint64_t state0) { * // Exponent for double values for [1.0 .. 2.0) * static const uint64_t kExponentBits = uint64_t{0x3FF0000000000000}; * uint64_t random = (state0 >> 12) | kExponentBits; * return base::bit_cast<double>(random) - 1; * } * ``` * * - New Impl: https://github.com/v8/v8/blob/1c3a9c08e932e87b04c7bf9ecc648e1f50d418fd/src/base/utils/random-number-generator.h#L111 * ``` * // Static and exposed for external use. * static inline double ToDouble(uint64_t state0) { * // Get a random [0,2**53) integer value (up to MAX_SAFE_INTEGER) by dropping * // 11 bits of the state. * double random_0_to_2_53 = static_cast<double>(state0 >> 11); * // Map this to [0,1) by division with 2**53. * constexpr double k2_53{static_cast<uint64_t>(1) << 53}; * return random_0_to_2_53 / k2_53; * } * ``` * */ export default class NodeRandomnessPredictor { #private; sequence: number[]; constructor(sequence?: number[]); predictNext(): Promise<number>; setNodeVersion(version: SemanticVersion): void; }