CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-jetbrains-kotlin--kotlin-stdlib-wasm-wasi

Kotlin Standard Library implementation for WebAssembly System Interface (WASI) platform providing essential I/O, time, random, UUID, and reflection capabilities.

Pending
Overview
Eval results
Files

random.mddocs/

Random Number Generation

Overview

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.

API Reference

Platform Random Object

/**
 * Platform-specific default random number generator for WASI.
 * Uses WASI's cryptographically secure random_get system call.
 */
object PlatformRandom : Random

Random Class Methods

All 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>

Usage Examples

Basic Random Numbers

// 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()

Random Byte Arrays

// 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)

Range-Based Random Generation

// 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 Types

// 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)

Random Collection Operations

// 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)

Secure Random Generation

// 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)

Implementation Details

WASI System Call Integration

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): Int

Cryptographic Security

The WASI random_get system call provides:

  • Hardware Entropy: Uses hardware random number generators when available
  • Cryptographic Quality: Suitable for cryptographic applications
  • High Entropy: Provides high-quality randomness for security-sensitive operations
  • Thread Safety: Safe for concurrent access across multiple contexts

Memory Management

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
}

Error Handling

Random generation handles WASI-specific errors:

  • EFAULT: Invalid buffer address
  • EIO: I/O error accessing entropy source
  • ENOSYS: Random generation not supported by runtime

Errors are translated to appropriate Kotlin exceptions.

Security Considerations

Cryptographic Suitability

The WASI random implementation is suitable for:

  • Key Generation: Cryptographic keys and initialization vectors
  • Token Generation: Session tokens and API keys
  • Salt Generation: Password hashing salts
  • Nonce Generation: Cryptographic nonces
  • UUID Generation: Cryptographically secure UUIDs

Best Practices

// 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

Avoiding Common Pitfalls

// 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)

Performance Characteristics

System Call Overhead

  • Batch Generation: For large amounts of random data, use nextBytes(size) instead of multiple calls
  • Caching: The implementation may cache random data internally to reduce system calls
  • Memory Efficiency: Direct memory allocation avoids unnecessary copying

Optimization Examples

// 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 data

Install with Tessl CLI

npx tessl i tessl/maven-org-jetbrains-kotlin--kotlin-stdlib-wasm-wasi

docs

console-io.md

exceptions.md

index.md

random.md

reflection.md

time.md

uuid.md

tile.json