0
# Random Number Generation
1
2
Cross-platform random number generation with cryptographically strong fallbacks and unified API across browser and Node.js environments. Provides secure random bytes generation with automatic platform detection and fallback mechanisms.
3
4
## Capabilities
5
6
### Random Namespace
7
8
Provides cryptographically strong random number generation with automatic platform detection and fallback.
9
10
```typescript { .api }
11
/**
12
* The namespace for random number related functionality.
13
*/
14
namespace Random {
15
/**
16
* A function which generates random bytes.
17
*
18
* @param buffer - The `Uint8Array` to fill with random bytes.
19
*
20
* Notes:
21
* A cryptographically strong random number generator will be used if
22
* available. Otherwise, `Math.random` will be used as a fallback for
23
* randomness.
24
*
25
* The following RNGs are supported, listed in order of precedence:
26
* - `window.crypto.getRandomValues` (Modern browsers)
27
* - `window.msCrypto.getRandomValues` (IE 11)
28
* - `require('crypto').randomFillSync` (Node.js 7+)
29
* - `require('crypto').randomBytes` (Node.js 0.10+)
30
* - `Math.random` (Fallback)
31
*/
32
const getRandomValues: (buffer: Uint8Array) => void;
33
}
34
```
35
36
### Fallback Function
37
38
Internal fallback implementation using Math.random for environments without crypto support.
39
40
```typescript { .api }
41
/**
42
* Fallback random values generator using Math.random
43
* @param buffer - The Uint8Array to fill with pseudo-random bytes
44
*/
45
function fallbackRandomValues(buffer: Uint8Array): void;
46
```
47
48
**Usage Examples:**
49
50
```typescript
51
import { Random } from "@lumino/coreutils";
52
53
// Generate random bytes
54
const buffer = new Uint8Array(16);
55
Random.getRandomValues(buffer);
56
console.log(buffer); // Uint8Array with random values
57
58
// Generate random numbers
59
const randomBytes = new Uint8Array(4);
60
Random.getRandomValues(randomBytes);
61
62
// Convert to random integer (0 to 255 for each byte)
63
const randomInt = randomBytes[0];
64
console.log("Random integer (0-255):", randomInt);
65
66
// Generate random float (0 to 1)
67
const floatBytes = new Uint8Array(4);
68
Random.getRandomValues(floatBytes);
69
const randomFloat = (floatBytes[0] << 24 | floatBytes[1] << 16 | floatBytes[2] << 8 | floatBytes[3]) / 0x100000000;
70
console.log("Random float (0-1):", randomFloat);
71
```
72
73
### Common Use Cases
74
75
**Secure Random Tokens:**
76
77
```typescript
78
import { Random } from "@lumino/coreutils";
79
80
function generateSecureToken(length: number = 32): string {
81
const buffer = new Uint8Array(length);
82
Random.getRandomValues(buffer);
83
84
// Convert to hexadecimal string
85
return Array.from(buffer)
86
.map(b => b.toString(16).padStart(2, '0'))
87
.join('');
88
}
89
90
// Usage
91
const sessionToken = generateSecureToken(16); // 32 character hex string
92
const apiKey = generateSecureToken(32); // 64 character hex string
93
94
console.log("Session token:", sessionToken);
95
console.log("API key:", apiKey);
96
```
97
98
**Random String Generation:**
99
100
```typescript
101
import { Random } from "@lumino/coreutils";
102
103
function generateRandomString(length: number, charset: string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'): string {
104
const buffer = new Uint8Array(length);
105
Random.getRandomValues(buffer);
106
107
let result = '';
108
for (let i = 0; i < length; i++) {
109
result += charset[buffer[i] % charset.length];
110
}
111
112
return result;
113
}
114
115
// Usage
116
const randomPassword = generateRandomString(12);
117
const randomId = generateRandomString(8, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789');
118
const randomSlug = generateRandomString(10, 'abcdefghijklmnopqrstuvwxyz0123456789');
119
120
console.log("Random password:", randomPassword);
121
console.log("Random ID:", randomId);
122
console.log("Random slug:", randomSlug);
123
```
124
125
**Secure Random Numbers:**
126
127
```typescript
128
import { Random } from "@lumino/coreutils";
129
130
function getRandomInt(min: number, max: number): number {
131
const range = max - min + 1;
132
const buffer = new Uint8Array(4);
133
134
// Generate random bytes until we get a value in range
135
// This prevents modulo bias
136
let result;
137
do {
138
Random.getRandomValues(buffer);
139
result = (buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]) >>> 0;
140
} while (result >= Math.floor(0x100000000 / range) * range);
141
142
return min + (result % range);
143
}
144
145
function getRandomFloat(min: number = 0, max: number = 1): number {
146
const buffer = new Uint8Array(4);
147
Random.getRandomValues(buffer);
148
const randomValue = (buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]) >>> 0;
149
return min + (randomValue / 0x100000000) * (max - min);
150
}
151
152
// Usage
153
const randomDiceRoll = getRandomInt(1, 6); // 1-6
154
const randomIndex = getRandomInt(0, 99); // 0-99
155
const randomPrice = getRandomFloat(10.0, 100.0); // 10.0-100.0
156
157
console.log("Dice roll:", randomDiceRoll);
158
console.log("Random index:", randomIndex);
159
console.log("Random price:", randomPrice.toFixed(2));
160
```
161
162
**Cryptographic Salt Generation:**
163
164
```typescript
165
import { Random } from "@lumino/coreutils";
166
167
function generateSalt(length: number = 16): Uint8Array {
168
const salt = new Uint8Array(length);
169
Random.getRandomValues(salt);
170
return salt;
171
}
172
173
function saltToHex(salt: Uint8Array): string {
174
return Array.from(salt)
175
.map(b => b.toString(16).padStart(2, '0'))
176
.join('');
177
}
178
179
function saltToBase64(salt: Uint8Array): string {
180
// Convert to base64 (simple implementation)
181
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
182
let result = '';
183
for (let i = 0; i < salt.length; i += 3) {
184
const a = salt[i];
185
const b = salt[i + 1] || 0;
186
const c = salt[i + 2] || 0;
187
188
const bitmap = (a << 16) | (b << 8) | c;
189
result += chars[(bitmap >> 18) & 63];
190
result += chars[(bitmap >> 12) & 63];
191
result += i + 1 < salt.length ? chars[(bitmap >> 6) & 63] : '=';
192
result += i + 2 < salt.length ? chars[bitmap & 63] : '=';
193
}
194
return result;
195
}
196
197
// Usage
198
const salt = generateSalt(16);
199
const saltHex = saltToHex(salt);
200
const saltBase64 = saltToBase64(salt);
201
202
console.log("Salt (raw):", salt);
203
console.log("Salt (hex):", saltHex);
204
console.log("Salt (base64):", saltBase64);
205
```
206
207
**Random Array Shuffling:**
208
209
```typescript
210
import { Random } from "@lumino/coreutils";
211
212
function shuffleArray<T>(array: T[]): T[] {
213
const shuffled = [...array];
214
215
for (let i = shuffled.length - 1; i > 0; i--) {
216
// Generate random index using secure random
217
const buffer = new Uint8Array(4);
218
Random.getRandomValues(buffer);
219
const randomValue = (buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]) >>> 0;
220
const j = randomValue % (i + 1);
221
222
// Swap elements
223
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
224
}
225
226
return shuffled;
227
}
228
229
function getRandomElement<T>(array: T[]): T {
230
const buffer = new Uint8Array(4);
231
Random.getRandomValues(buffer);
232
const randomValue = (buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]) >>> 0;
233
const index = randomValue % array.length;
234
return array[index];
235
}
236
237
// Usage
238
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
239
const shuffledNumbers = shuffleArray(numbers);
240
console.log("Original:", numbers);
241
console.log("Shuffled:", shuffledNumbers);
242
243
const colors = ['red', 'blue', 'green', 'yellow', 'purple'];
244
const randomColor = getRandomElement(colors);
245
console.log("Random color:", randomColor);
246
```
247
248
## Platform Support
249
250
The Random namespace automatically detects the available cryptographic APIs:
251
252
### Browser Support
253
- **Modern browsers**: Uses `window.crypto.getRandomValues()`
254
- **Internet Explorer 11**: Uses `window.msCrypto.getRandomValues()`
255
- **Fallback**: Uses `Math.random()` if crypto APIs unavailable
256
257
### Node.js Support
258
- **Node.js 7+**: Uses `crypto.randomFillSync()`
259
- **Node.js 0.10+**: Uses `crypto.randomBytes()`
260
- **Fallback**: Uses `Math.random()` if crypto module unavailable
261
262
### Security Considerations
263
264
- The fallback `Math.random()` implementation is **not cryptographically secure**
265
- Use only for non-security-critical randomness when crypto APIs are unavailable
266
- For security-sensitive applications, ensure crypto APIs are available in your target environment
267
- The implementation uses secure random sources when available, making it suitable for generating tokens, salts, and other security-critical random data