Kotlin Standard Library implementation for WebAssembly System Interface (WASI) platform providing essential I/O, time, random, UUID, and reflection capabilities.
—
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.
/**
* Platform-specific default random number generator for WASI.
* Uses WASI's cryptographically secure random_get system call.
*/
object PlatformRandom : RandomAll standard Kotlin Random class methods are available through the WASI-specific implementation:
object Random {
/**
* Gets the next random [Int] from the random number generator.
* @return a random integer
*/
fun nextInt(): Int
/**
* Gets a random non-negative integer less than [until].
* @param until the exclusive upper bound (must be positive)
* @return a random integer from 0 (inclusive) to [until] (exclusive)
*/
fun nextInt(until: Int): Int
/**
* Gets a random integer in the specified range.
* @param from the inclusive lower bound
* @param until the exclusive upper bound
* @return a random integer from [from] (inclusive) to [until] (exclusive)
*/
fun nextInt(from: Int, until: Int): Int
/**
* Gets the next random [Long] from the random number generator.
* @return a random long integer
*/
fun nextLong(): Long
/**
* Gets a random non-negative long less than [until].
* @param until the exclusive upper bound (must be positive)
* @return a random long from 0 (inclusive) to [until] (exclusive)
*/
fun nextLong(until: Long): Long
/**
* Gets a random long in the specified range.
* @param from the inclusive lower bound
* @param until the exclusive upper bound
* @return a random long from [from] (inclusive) to [until] (exclusive)
*/
fun nextLong(from: Long, until: Long): Long
/**
* Gets the next random [Boolean] value.
* @return a random boolean
*/
fun nextBoolean(): Boolean
/**
* Gets the next random [Double] value between 0.0 (inclusive) and 1.0 (exclusive).
* @return a random double
*/
fun nextDouble(): Double
/**
* Gets a random double in the specified range.
* @param until the exclusive upper bound
* @return a random double from 0.0 (inclusive) to [until] (exclusive)
*/
fun nextDouble(until: Double): Double
/**
* Gets a random double in the specified range.
* @param from the inclusive lower bound
* @param until the exclusive upper bound
* @return a random double from [from] (inclusive) to [until] (exclusive)
*/
fun nextDouble(from: Double, until: Double): Double
/**
* Gets the next random [Float] value between 0.0 (inclusive) and 1.0 (exclusive).
* @return a random float
*/
fun nextFloat(): Float
/**
* Fills the specified byte array with random bytes.
* @param array the byte array to fill
*/
fun nextBytes(array: ByteArray): ByteArray
/**
* Creates a byte array of the specified [size] and fills it with random bytes.
* @param size the size of the byte array
* @return a byte array filled with random bytes
*/
fun nextBytes(size: Int): ByteArray
/**
* Fills a portion of the specified byte array with random bytes.
* @param array the byte array to fill
* @param fromIndex the start index (inclusive)
* @param toIndex the end index (exclusive)
* @return the same array that was passed in
*/
fun nextBytes(array: ByteArray, fromIndex: Int, toIndex: Int): ByteArray
}
/**
* Extension functions for range-based random generation
*/
fun Random.nextInt(range: IntRange): Int
fun Random.nextLong(range: LongRange): Long
/**
* Unsigned random number generation methods
*/
@SinceKotlin("1.5")
fun Random.nextUInt(): UInt
@SinceKotlin("1.5")
fun Random.nextUInt(until: UInt): UInt
@SinceKotlin("1.5")
fun Random.nextUInt(from: UInt, until: UInt): UInt
@SinceKotlin("1.5")
fun Random.nextUInt(range: UIntRange): UInt
@SinceKotlin("1.5")
fun Random.nextULong(): ULong
@SinceKotlin("1.5")
fun Random.nextULong(until: ULong): ULong
@SinceKotlin("1.5")
fun Random.nextULong(from: ULong, until: ULong): ULong
@SinceKotlin("1.5")
fun Random.nextULong(range: ULongRange): ULong
@SinceKotlin("1.3")
@ExperimentalUnsignedTypes
fun Random.nextUBytes(array: UByteArray): UByteArray
@SinceKotlin("1.3")
@ExperimentalUnsignedTypes
fun Random.nextUBytes(size: Int): UByteArray
/**
* Collection extension functions for random selection
*/
@SinceKotlin("1.3")
fun <T> Collection<T>.random(): T
@SinceKotlin("1.3")
fun <T> Collection<T>.random(random: Random): T
@SinceKotlin("1.4")
fun <T> Collection<T>.randomOrNull(): T?
@SinceKotlin("1.4")
fun <T> Collection<T>.randomOrNull(random: Random): T?
@SinceKotlin("1.3")
fun <T> Array<out T>.random(): T
@SinceKotlin("1.3")
fun <T> Array<out T>.random(random: Random): T
@SinceKotlin("1.4")
fun <T> MutableList<T>.shuffle(random: Random): Unit
@SinceKotlin("1.3")
fun <T> Iterable<T>.shuffled(random: Random): List<T>// Generate random integers
val randomInt = Random.nextInt()
val diceRoll = Random.nextInt(1, 7) // 1 to 6 inclusive
val percentage = Random.nextInt(0, 101) // 0 to 100 inclusive
// Generate random floating-point numbers
val randomDouble = Random.nextDouble() // 0.0 to 1.0
val temperature = Random.nextDouble(-10.0, 40.0) // -10.0 to 40.0
val randomFloat = Random.nextFloat()
// Generate random boolean
val coinFlip = Random.nextBoolean()// Generate random bytes for cryptographic use
val key = Random.nextBytes(32) // 256-bit key
val salt = Random.nextBytes(16) // 128-bit salt
val nonce = Random.nextBytes(12) // 96-bit nonce
// Fill existing array with random data
val buffer = ByteArray(1024)
Random.nextBytes(buffer)// Using IntRange
val diceRoll = Random.nextInt(1..6) // 1 to 6 inclusive
val percentage = Random.nextInt(0..100) // 0 to 100 inclusive
// Using LongRange
val largeRange = Random.nextLong(1_000_000L..10_000_000L)// Unsigned integers
val uintValue = Random.nextUInt()
val uintInRange = Random.nextUInt(1u, 100u)
val uintRange = Random.nextUInt(1u..100u)
// Unsigned longs
val ulongValue = Random.nextULong()
val ulongInRange = Random.nextULong(1uL, 1000uL)
// Unsigned byte arrays
val ubytes = Random.nextUBytes(16)// Shuffle a list
val numbers = mutableListOf(1, 2, 3, 4, 5)
numbers.shuffle(Random)
// Pick random element
val fruits = listOf("apple", "banana", "orange", "grape")
val randomFruit = fruits.random(Random)
val randomFruitOrNull = fruits.randomOrNull(Random) // returns null if empty
// Random sampling
val sample = numbers.shuffled(Random).take(3)
// Random element from arrays
val colors = arrayOf("red", "green", "blue")
val randomColor = colors.random(Random)// Generate cryptographically secure random data
fun generateSecureToken(length: Int): String {
val bytes = Random.nextBytes(length)
return bytes.joinToString("") { "%02x".format(it) }
}
// Generate secure session ID
val sessionId = generateSecureToken(32)
// Generate random password
fun generatePassword(length: Int): String {
val chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*"
return (1..length)
.map { chars[Random.nextInt(chars.length)] }
.joinToString("")
}
val password = generatePassword(16)Random number generation is implemented using the WASI random_get system call:
@WasmImport("wasi_snapshot_preview1", "random_get")
private external fun wasiRawRandomGet(buf: Int, bufLen: Int): IntThe WASI random_get system call provides:
Random byte generation uses efficient memory allocation:
// Scoped memory allocation for random data
MemoryAllocator.scoped { allocator ->
val buffer = allocator.allocate(size)
val result = wasiRawRandomGet(buffer.address.toInt(), size)
// Copy data and clean up automatically
}Random generation handles WASI-specific errors:
Errors are translated to appropriate Kotlin exceptions.
The WASI random implementation is suitable for:
// Always use the default Random for security-sensitive operations
// Don't create custom Random instances unless specifically needed
val secureKey = Random.nextBytes(32)
// For reproducible testing, use a seeded Random only in tests
// Never use seeded randoms in production for security-sensitive data// DON'T: Use system time or predictable values for seeds
// val badRandom = Random(System.currentTimeMillis())
// DO: Use the default Random instance
val goodRandom = Random.nextBytes(16)
// DON'T: Reuse random values for different purposes
// val value = Random.nextBytes(16)
// val key = value // Don't reuse
// val iv = value // Don't reuse
// DO: Generate separate random values
val key = Random.nextBytes(16)
val iv = Random.nextBytes(16)nextBytes(size) instead of multiple calls// Less efficient: Multiple system calls
val bytes = ByteArray(1000)
for (i in bytes.indices) {
bytes[i] = Random.nextInt(256).toByte()
}
// More efficient: Single system call
val bytes = Random.nextBytes(1000)
// Efficient for bulk operations
val largeBuffer = Random.nextBytes(1024 * 1024) // 1MB of random dataInstall with Tessl CLI
npx tessl i tessl/maven-org-jetbrains-kotlin--kotlin-stdlib-wasm-wasi