0
# Random Number Generation
1
2
## Overview
3
4
The Random Number Generation capabilities provide cryptographically secure random number generation using WASI's `random_get` system call. This ensures high-quality entropy for security-sensitive applications running in WASI environments.
5
6
## API Reference
7
8
### Platform Random Object
9
10
```kotlin { .api }
11
/**
12
* Platform-specific default random number generator for WASI.
13
* Uses WASI's cryptographically secure random_get system call.
14
*/
15
object PlatformRandom : Random
16
```
17
18
### Random Class Methods
19
20
All standard Kotlin `Random` class methods are available through the WASI-specific implementation:
21
22
```kotlin { .api }
23
object Random {
24
/**
25
* Gets the next random [Int] from the random number generator.
26
* @return a random integer
27
*/
28
fun nextInt(): Int
29
30
/**
31
* Gets a random non-negative integer less than [until].
32
* @param until the exclusive upper bound (must be positive)
33
* @return a random integer from 0 (inclusive) to [until] (exclusive)
34
*/
35
fun nextInt(until: Int): Int
36
37
/**
38
* Gets a random integer in the specified range.
39
* @param from the inclusive lower bound
40
* @param until the exclusive upper bound
41
* @return a random integer from [from] (inclusive) to [until] (exclusive)
42
*/
43
fun nextInt(from: Int, until: Int): Int
44
45
/**
46
* Gets the next random [Long] from the random number generator.
47
* @return a random long integer
48
*/
49
fun nextLong(): Long
50
51
/**
52
* Gets a random non-negative long less than [until].
53
* @param until the exclusive upper bound (must be positive)
54
* @return a random long from 0 (inclusive) to [until] (exclusive)
55
*/
56
fun nextLong(until: Long): Long
57
58
/**
59
* Gets a random long in the specified range.
60
* @param from the inclusive lower bound
61
* @param until the exclusive upper bound
62
* @return a random long from [from] (inclusive) to [until] (exclusive)
63
*/
64
fun nextLong(from: Long, until: Long): Long
65
66
/**
67
* Gets the next random [Boolean] value.
68
* @return a random boolean
69
*/
70
fun nextBoolean(): Boolean
71
72
/**
73
* Gets the next random [Double] value between 0.0 (inclusive) and 1.0 (exclusive).
74
* @return a random double
75
*/
76
fun nextDouble(): Double
77
78
/**
79
* Gets a random double in the specified range.
80
* @param until the exclusive upper bound
81
* @return a random double from 0.0 (inclusive) to [until] (exclusive)
82
*/
83
fun nextDouble(until: Double): Double
84
85
/**
86
* Gets a random double in the specified range.
87
* @param from the inclusive lower bound
88
* @param until the exclusive upper bound
89
* @return a random double from [from] (inclusive) to [until] (exclusive)
90
*/
91
fun nextDouble(from: Double, until: Double): Double
92
93
/**
94
* Gets the next random [Float] value between 0.0 (inclusive) and 1.0 (exclusive).
95
* @return a random float
96
*/
97
fun nextFloat(): Float
98
99
/**
100
* Fills the specified byte array with random bytes.
101
* @param array the byte array to fill
102
*/
103
fun nextBytes(array: ByteArray): ByteArray
104
105
/**
106
* Creates a byte array of the specified [size] and fills it with random bytes.
107
* @param size the size of the byte array
108
* @return a byte array filled with random bytes
109
*/
110
fun nextBytes(size: Int): ByteArray
111
112
/**
113
* Fills a portion of the specified byte array with random bytes.
114
* @param array the byte array to fill
115
* @param fromIndex the start index (inclusive)
116
* @param toIndex the end index (exclusive)
117
* @return the same array that was passed in
118
*/
119
fun nextBytes(array: ByteArray, fromIndex: Int, toIndex: Int): ByteArray
120
}
121
122
/**
123
* Extension functions for range-based random generation
124
*/
125
fun Random.nextInt(range: IntRange): Int
126
fun Random.nextLong(range: LongRange): Long
127
128
/**
129
* Unsigned random number generation methods
130
*/
131
@SinceKotlin("1.5")
132
fun Random.nextUInt(): UInt
133
@SinceKotlin("1.5")
134
fun Random.nextUInt(until: UInt): UInt
135
@SinceKotlin("1.5")
136
fun Random.nextUInt(from: UInt, until: UInt): UInt
137
@SinceKotlin("1.5")
138
fun Random.nextUInt(range: UIntRange): UInt
139
140
@SinceKotlin("1.5")
141
fun Random.nextULong(): ULong
142
@SinceKotlin("1.5")
143
fun Random.nextULong(until: ULong): ULong
144
@SinceKotlin("1.5")
145
fun Random.nextULong(from: ULong, until: ULong): ULong
146
@SinceKotlin("1.5")
147
fun Random.nextULong(range: ULongRange): ULong
148
149
@SinceKotlin("1.3")
150
@ExperimentalUnsignedTypes
151
fun Random.nextUBytes(array: UByteArray): UByteArray
152
@SinceKotlin("1.3")
153
@ExperimentalUnsignedTypes
154
fun Random.nextUBytes(size: Int): UByteArray
155
156
/**
157
* Collection extension functions for random selection
158
*/
159
@SinceKotlin("1.3")
160
fun <T> Collection<T>.random(): T
161
@SinceKotlin("1.3")
162
fun <T> Collection<T>.random(random: Random): T
163
@SinceKotlin("1.4")
164
fun <T> Collection<T>.randomOrNull(): T?
165
@SinceKotlin("1.4")
166
fun <T> Collection<T>.randomOrNull(random: Random): T?
167
168
@SinceKotlin("1.3")
169
fun <T> Array<out T>.random(): T
170
@SinceKotlin("1.3")
171
fun <T> Array<out T>.random(random: Random): T
172
173
@SinceKotlin("1.4")
174
fun <T> MutableList<T>.shuffle(random: Random): Unit
175
@SinceKotlin("1.3")
176
fun <T> Iterable<T>.shuffled(random: Random): List<T>
177
```
178
179
## Usage Examples
180
181
### Basic Random Numbers
182
183
```kotlin
184
// Generate random integers
185
val randomInt = Random.nextInt()
186
val diceRoll = Random.nextInt(1, 7) // 1 to 6 inclusive
187
val percentage = Random.nextInt(0, 101) // 0 to 100 inclusive
188
189
// Generate random floating-point numbers
190
val randomDouble = Random.nextDouble() // 0.0 to 1.0
191
val temperature = Random.nextDouble(-10.0, 40.0) // -10.0 to 40.0
192
val randomFloat = Random.nextFloat()
193
194
// Generate random boolean
195
val coinFlip = Random.nextBoolean()
196
```
197
198
### Random Byte Arrays
199
200
```kotlin
201
// Generate random bytes for cryptographic use
202
val key = Random.nextBytes(32) // 256-bit key
203
val salt = Random.nextBytes(16) // 128-bit salt
204
val nonce = Random.nextBytes(12) // 96-bit nonce
205
206
// Fill existing array with random data
207
val buffer = ByteArray(1024)
208
Random.nextBytes(buffer)
209
```
210
211
### Range-Based Random Generation
212
213
```kotlin
214
// Using IntRange
215
val diceRoll = Random.nextInt(1..6) // 1 to 6 inclusive
216
val percentage = Random.nextInt(0..100) // 0 to 100 inclusive
217
218
// Using LongRange
219
val largeRange = Random.nextLong(1_000_000L..10_000_000L)
220
```
221
222
### Unsigned Types
223
224
```kotlin
225
// Unsigned integers
226
val uintValue = Random.nextUInt()
227
val uintInRange = Random.nextUInt(1u, 100u)
228
val uintRange = Random.nextUInt(1u..100u)
229
230
// Unsigned longs
231
val ulongValue = Random.nextULong()
232
val ulongInRange = Random.nextULong(1uL, 1000uL)
233
234
// Unsigned byte arrays
235
val ubytes = Random.nextUBytes(16)
236
```
237
238
### Random Collection Operations
239
240
```kotlin
241
// Shuffle a list
242
val numbers = mutableListOf(1, 2, 3, 4, 5)
243
numbers.shuffle(Random)
244
245
// Pick random element
246
val fruits = listOf("apple", "banana", "orange", "grape")
247
val randomFruit = fruits.random(Random)
248
val randomFruitOrNull = fruits.randomOrNull(Random) // returns null if empty
249
250
// Random sampling
251
val sample = numbers.shuffled(Random).take(3)
252
253
// Random element from arrays
254
val colors = arrayOf("red", "green", "blue")
255
val randomColor = colors.random(Random)
256
```
257
258
### Secure Random Generation
259
260
```kotlin
261
// Generate cryptographically secure random data
262
fun generateSecureToken(length: Int): String {
263
val bytes = Random.nextBytes(length)
264
return bytes.joinToString("") { "%02x".format(it) }
265
}
266
267
// Generate secure session ID
268
val sessionId = generateSecureToken(32)
269
270
// Generate random password
271
fun generatePassword(length: Int): String {
272
val chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*"
273
return (1..length)
274
.map { chars[Random.nextInt(chars.length)] }
275
.joinToString("")
276
}
277
278
val password = generatePassword(16)
279
```
280
281
## Implementation Details
282
283
### WASI System Call Integration
284
285
Random number generation is implemented using the WASI `random_get` system call:
286
287
```kotlin
288
@WasmImport("wasi_snapshot_preview1", "random_get")
289
private external fun wasiRawRandomGet(buf: Int, bufLen: Int): Int
290
```
291
292
### Cryptographic Security
293
294
The WASI `random_get` system call provides:
295
296
- **Hardware Entropy**: Uses hardware random number generators when available
297
- **Cryptographic Quality**: Suitable for cryptographic applications
298
- **High Entropy**: Provides high-quality randomness for security-sensitive operations
299
- **Thread Safety**: Safe for concurrent access across multiple contexts
300
301
### Memory Management
302
303
Random byte generation uses efficient memory allocation:
304
305
```kotlin
306
// Scoped memory allocation for random data
307
MemoryAllocator.scoped { allocator ->
308
val buffer = allocator.allocate(size)
309
val result = wasiRawRandomGet(buffer.address.toInt(), size)
310
// Copy data and clean up automatically
311
}
312
```
313
314
### Error Handling
315
316
Random generation handles WASI-specific errors:
317
318
- **EFAULT**: Invalid buffer address
319
- **EIO**: I/O error accessing entropy source
320
- **ENOSYS**: Random generation not supported by runtime
321
322
Errors are translated to appropriate Kotlin exceptions.
323
324
## Security Considerations
325
326
### Cryptographic Suitability
327
328
The WASI random implementation is suitable for:
329
330
- **Key Generation**: Cryptographic keys and initialization vectors
331
- **Token Generation**: Session tokens and API keys
332
- **Salt Generation**: Password hashing salts
333
- **Nonce Generation**: Cryptographic nonces
334
- **UUID Generation**: Cryptographically secure UUIDs
335
336
### Best Practices
337
338
```kotlin
339
// Always use the default Random for security-sensitive operations
340
// Don't create custom Random instances unless specifically needed
341
val secureKey = Random.nextBytes(32)
342
343
// For reproducible testing, use a seeded Random only in tests
344
// Never use seeded randoms in production for security-sensitive data
345
```
346
347
### Avoiding Common Pitfalls
348
349
```kotlin
350
// DON'T: Use system time or predictable values for seeds
351
// val badRandom = Random(System.currentTimeMillis())
352
353
// DO: Use the default Random instance
354
val goodRandom = Random.nextBytes(16)
355
356
// DON'T: Reuse random values for different purposes
357
// val value = Random.nextBytes(16)
358
// val key = value // Don't reuse
359
// val iv = value // Don't reuse
360
361
// DO: Generate separate random values
362
val key = Random.nextBytes(16)
363
val iv = Random.nextBytes(16)
364
```
365
366
## Performance Characteristics
367
368
### System Call Overhead
369
370
- **Batch Generation**: For large amounts of random data, use `nextBytes(size)` instead of multiple calls
371
- **Caching**: The implementation may cache random data internally to reduce system calls
372
- **Memory Efficiency**: Direct memory allocation avoids unnecessary copying
373
374
### Optimization Examples
375
376
```kotlin
377
// Less efficient: Multiple system calls
378
val bytes = ByteArray(1000)
379
for (i in bytes.indices) {
380
bytes[i] = Random.nextInt(256).toByte()
381
}
382
383
// More efficient: Single system call
384
val bytes = Random.nextBytes(1000)
385
386
// Efficient for bulk operations
387
val largeBuffer = Random.nextBytes(1024 * 1024) // 1MB of random data
388
```