or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

console-io.mdexceptions.mdindex.mdrandom.mdreflection.mdtime.mduuid.md

random.mddocs/

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

```