skip to content

How does kotlin.random.Random work in the common stdlib, and how would you produce reproducible random sequences across platforms?

level: middleimportance: should knowfreq 45%

answer

  1. Random(seed) = deterministic, same across platforms
  2. Random.Default backs top-level Random.nextInt
  3. Ranges/collections: .random(rng), .shuffled(rng)
  4. PRNG not CSPRNG — no secure RNG in common
  5. nextInt(from, until) is half-open

basics

~10 s

kotlin.random.Random is the multiplatform random generator. Use Random.nextInt() for one-off values, and create Random(seed) with a fixed seed to get the same sequence every run, on any platform.

solid answer

~30 s

`kotlin.random.Random` is the common-stdlib random number generator, available from commonMain on all targets. `Random.Default` (also reachable as the `Random` companion) backs top-level calls like `Random.nextInt(1, 7)`. For **reproducibility** you construct a seeded instance: `Random(42)` returns a generator whose sequence is deterministic and **identical across platforms**, because Kotlin specifies the algorithm (an xorshift-based generator) rather than delegating to the platform RNG. Useful APIs: `nextInt()/nextInt(until)/nextInt(from, until)`, `nextLong`, `nextDouble`, `nextBoolean`, `nextBytes(ByteArray)`, and extensions like `(1..6).random(rng)`, `list.random(rng)`, `list.shuffled(rng)`. Important: it is **not** cryptographically secure — for secrets use a platform CSPRNG via expect/actual. Also note `Random.Default` is not guaranteed thread-safe for concurrent mutation.

code

kotlin · 7 lines
kotlin
import kotlin.random.Random

fun deterministicDeck(seed: Long): List<Int> {
    val rng = Random(seed)
    return (1..52).toList().shuffled(rng)
}
// same seed -> identical deck on JVM, JS, Native

go deeper

for a junior

Can call Random.nextInt and knows a seed makes results repeatable.

for a middle

Constructs Random(seed) for deterministic tests and uses range/collection extensions.

for a senior

Distinguishes PRNG vs CSPRNG and routes secure randomness through expect/actual; aware of cross-platform determinism.

for a principal

Defines org policy on randomness (test determinism vs. security), and reasons about RNG state, contention, and reproducibility guarantees.

## The common RNG `kotlin.random.Random` is an **abstract class** in the common stdlib. Two ways to get an instance: - `Random.Default` — the shared global generator; `Random.nextInt()` etc. delegate to it. - `Random(seed)` — a factory that returns a **seeded**, deterministic generator. `seed` can be `Int` or `Long`. ```kotlin import kotlin.random.Random val rng = Random(42) println(rng.nextInt(0, 100)) // same value every run, every platform println(rng.nextDouble()) ``` ## Why it is reproducible across platforms Unlike java.util.Random-by-platform, Kotlin's `Random` defines its own algorithm (a well-specified xorshift variant) in the common code. So a seeded sequence is **bit-for-bit identical** on JVM, JS, and Native — which is exactly what you want for deterministic tests, procedural generation, and shared simulations. ## Core API - `nextInt()`, `nextInt(until)`, `nextInt(from, until)` (half-open range). - `nextLong`, `nextDouble(until)`, `nextBoolean`, `nextFloat`. - `nextBytes(ByteArray)` to fill a buffer. - Collection/range extensions taking a `Random`: `(1..6).random(rng)`, `list.random(rng)`, `list.shuffled(rng)`. ## Not for security `kotlin.random.Random` is a **PRNG**, not a CSPRNG. Never use it for tokens, keys, or salts. There is `Random.nextInt` etc. but no common secure RNG; for security use a platform generator via expect/actual: ```kotlin // commonMain expect fun secureBytes(n: Int): ByteArray // jvmMain: java.security.SecureRandom; nativeMain/jsMain: platform CSPRNG ``` ## Concurrency `Random.Default` is fine for casual use but is not specified as safe under concurrent mutation; give each thread/coroutine its own seeded instance if determinism or contention matters.

  • A teammate uses kotlin.random.Random to generate password-reset tokens. What do you say?
    Stop — it's a non-cryptographic PRNG and its output is predictable from the seed/state. Use a platform CSPRNG (SecureRandom on JVM) via expect/actual.
  • Why might Random(42) give different results than java.util.Random(42)?
    Kotlin's Random uses its own algorithm, not java.util.Random's, precisely so the sequence is consistent across all KMP targets.

A seed is like a recipe ID: hand the same ID to any kitchen (platform) and you get the exact same dish (sequence).

saying these in an interview costs you the question

  • Uses kotlin.random.Random for cryptographic tokens
  • Assumes nextInt(from, until) includes the upper bound
  • Thinks Random.Default is thread-safe for shared mutation
  • Believes seeded results differ per platform

context