Commit | Line | Data |
---|---|---|
9e6467bf | 1 | import crypto, { webcrypto } from 'node:crypto' |
343cfe4f JB |
2 | |
3 | /** | |
4 | * Generate a cryptographically secure random number in the [0,1[ range | |
343cfe4f JB |
5 | * @returns |
6 | */ | |
be798e12 | 7 | export function secureRandom () { |
343cfe4f JB |
8 | return crypto.randomBytes(4).readUInt32LE() / 0x100000000 |
9 | } | |
10 | ||
99d76a65 | 11 | /** |
06e5b856 | 12 | * Generate a cryptographically secure random number in the [0,1[ range |
483585cc | 13 | * @returns |
99d76a65 | 14 | */ |
be798e12 | 15 | export function secureRandomWithRandomValues () { |
a551f316 | 16 | return webcrypto.getRandomValues(new Uint32Array(1))[0] / 0x100000000 |
99d76a65 JB |
17 | } |
18 | ||
e9bfc28e JB |
19 | /** |
20 | * @param max | |
21 | * @param min | |
7fd91296 | 22 | * @returns |
e9bfc28e | 23 | */ |
be798e12 | 24 | export function generateRandomInteger (max = Number.MAX_SAFE_INTEGER, min = 0) { |
aa418e78 | 25 | if (max < min || max < 0 || min < 0) { |
343cfe4f JB |
26 | throw new RangeError('Invalid interval') |
27 | } | |
28 | max = Math.floor(max) | |
da504870 | 29 | if (min != null && min !== 0) { |
343cfe4f JB |
30 | min = Math.ceil(min) |
31 | return Math.floor(secureRandom() * (max - min + 1)) + min | |
ed2968f2 | 32 | } |
343cfe4f | 33 | return Math.floor(secureRandom() * (max + 1)) |
ed2968f2 JB |
34 | } |
35 | ||
aa418e78 JB |
36 | /** |
37 | * | |
38 | * @param max | |
39 | * @param min | |
aa418e78 JB |
40 | * @returns |
41 | */ | |
be798e12 | 42 | export function generateRandomFloat (max = Number.MAX_VALUE, min = 0) { |
768c0780 JB |
43 | if (max < min) { |
44 | throw new RangeError('Invalid interval') | |
45 | } | |
46 | if (max - min === Infinity) { | |
aa418e78 JB |
47 | throw new RangeError('Invalid interval') |
48 | } | |
768c0780 | 49 | return (crypto.randomBytes(4).readUInt32LE() / 0xffffffff) * (max - min) + min |
aa418e78 JB |
50 | } |
51 | ||
ed40d2b0 JB |
52 | /** |
53 | * | |
54 | * @param size | |
55 | * @param max | |
feb629fe | 56 | * @param numberGenerator |
67bc7194 | 57 | * @returns |
ed40d2b0 | 58 | */ |
be798e12 | 59 | export function generateRandomNumberArray ( |
feb629fe JB |
60 | size, |
61 | max = Number.MAX_VALUE, | |
62 | numberGenerator = generateRandomFloat | |
63 | ) { | |
64 | const array = [] | |
ed40d2b0 | 65 | for (let i = 0; i < size; i++) { |
feb629fe | 66 | array.push(numberGenerator(max)) |
ed40d2b0 | 67 | } |
feb629fe JB |
68 | return array |
69 | } | |
70 | ||
5b907dbf JB |
71 | /** |
72 | * | |
73 | * @param sizeMax | |
74 | * @param numberMax | |
75 | * @param numberGenerator | |
76 | * @returns | |
77 | */ | |
be798e12 | 78 | export function generateRandomObject ( |
5b907dbf JB |
79 | sizeMax = 500, |
80 | numberMax = Number.MAX_VALUE, | |
81 | numberGenerator = generateRandomFloat | |
82 | ) { | |
83 | const size = generateRandomInteger(sizeMax) | |
84 | const object = {} | |
85 | for (let i = 0; i < size; i++) { | |
86 | object[i.toString()] = numberGenerator(numberMax) | |
87 | } | |
8e1fbc06 | 88 | return object |
5b907dbf JB |
89 | } |
90 | ||
a9c78d5d JB |
91 | /** |
92 | * @param ms | |
7fd91296 | 93 | * @returns |
a9c78d5d | 94 | */ |
be798e12 | 95 | export async function sleep (ms) { |
f913c68c | 96 | return new Promise(resolve => setTimeout(resolve, ms)) |
a9c78d5d | 97 | } |