1. Introduction

This short tutorial will demonstrate how to generate a random number using Kotlin.

2. Random Number Using java.lang.Math

The easiest way to generate a random number in Kotlin is to use java.lang.Math. Below example will generate a random double number between 0 and 1.

@Test
fun whenRandomNumberWithJavaUtilMath_thenResultIsBetween0And1() {
    val randomNumber = Math.random()
    assertTrue { randomNumber >= 0 }
    assertTrue { randomNumber < 1 }
}

3. Random Number Using ThreadLocalRandom

We can also use java.util.concurrent.ThreadLocalRandom to generate a random double, integer, or long value. Integer and long values generated this way can be positive or negative.

ThreadLocalRandom is thread-safe and provides better performance in a multithreaded environment because it provides a separate Random object for every thread and thus reduces contention between threads:

@Test
fun whenRandomNumberWithJavaThreadLocalRandom_thenResultsInDefaultRanges() {
    val randomDouble = ThreadLocalRandom.current().nextDouble()
    val randomInteger = ThreadLocalRandom.current().nextInt()
    val randomLong = ThreadLocalRandom.current().nextLong()
    assertTrue { randomDouble >= 0 }
    assertTrue { randomDouble < 1 }
    assertTrue { randomInteger >= Integer.MIN_VALUE }
    assertTrue { randomInteger < Integer.MAX_VALUE }
    assertTrue { randomLong >= Long.MIN_VALUE }
    assertTrue { randomLong < Long.MAX_VALUE }
}

4. Random Number Using Kotlin.js

We can also generate a random double using the Math class from the kotlin.js library.

@Test
fun whenRandomNumberWithKotlinJSMath_thenResultIsBetween0And1() {
    val randomDouble = Math.random()
    assertTrue { randomDouble >=0 }
    assertTrue { randomDouble < 1 }
}

5. Random Number in a Given Range Using Pure Kotlin

Using pure Kotlin, we can create a list of numbers, shuffle it, and then take the first element from that list:

@Test
fun whenRandomNumberWithKotlinNumberRange_thenResultInGivenRange() {
    val randomInteger = (1..12).shuffled().first()
    assertTrue { randomInteger >= 1 }
    assertTrue { randomInteger <= 12 }
}

6. Random Number in a Given Range Using ThreadLocalRandom

ThreadLocalRandom, presented in section 3, can also be used to generate a random number in a given range:

@Test
fun whenRandomNumberWithJavaThreadLocalRandom_thenResultsInGivenRanges() {
    val randomDouble = ThreadLocalRandom.current().nextDouble(1.0, 10.0)
    val randomInteger = ThreadLocalRandom.current().nextInt(1, 10)
    val randomLong = ThreadLocalRandom.current().nextLong(1, 10)
    assertTrue { randomDouble >= 1 }
    assertTrue { randomDouble < 10 }
    assertTrue { randomInteger >= 1 }
    assertTrue { randomInteger < 10 }
    assertTrue { randomLong >= 1 }
    assertTrue { randomLong < 10 }
}

7. Pseudo vs. Secure Random Number Generators

Standard JDK implementations of java.util.Random use a Linear Congruential Generator to provide random numbers. The problem with this algorithm is that it’s not cryptographically strong, and attackers could predict its outputs.

To overcome this issue, we should use java.security.SecureRandom in places where we need good security:

fun whenRandomNumberWithJavaSecureRandom_thenResultsInGivenRanges() {
    val secureRandom = SecureRandom()
    secureRandom.nextInt(100)
    assertTrue { randomLong >= 0 }
    assertTrue { randomLong < 100 }
}

SecureRandom produces cryptographically strong random values using a cryptographically strong pseudo-random number generator (CSPRNG).

Applications shouldn’t use other ways of generating a secure random number in security-related places.

8. Generating Non-Repeating Random Numbers in Kotlin

In some scenarios, we might need to generate a sequence of random numbers where each number appears only once. Kotlin provides a few different ways to do this.

8.1. Using shuffled()

We already mentioned using shuffled() for generating a random number if section 5. However, it also can be used to create a collection of non-repeating random numbers. It can randomize the order of the numbers in the range, ensuring that each number only appears once:

@Test
fun whenRandomNonRepeatingNumbersWithShuffle_thenResultsAreUnique() {
    val randomNumbers = (1..10).shuffled().take(5)
    assertTrue { randomNumbers.distinct().size == randomNumbers.size }
}

In this example, we create a range from 1 to 10, shuffle it to randomize the order, and then take the first five numbers. The shuffled() function ensures that no number appears more than once.

8.2. Using Sequences

We can use generateSequence along with the distinct() function to generate a sequence of non-repeating random numbers:

@Test
fun whenRandomNonRepeatingNumbersWithSequence_thenResultsAreUnique() {
    val randomNumbers = generateSequence { Random.nextInt(1, 11) }.distinct().take(5).toList()
    assertTrue { randomNumbers.distinct().size == randomNumbers.size }
}

We created a sequence that generates random numbers between 1 and 10. After that, we use the distinct() function to filter out duplicate numbers and take the first five unique numbers.

9. Conclusion

In this article, we’ve learned a few ways to generate a random number in Kotlin.

As always, all code presented in this tutorial can be found over on GitHub.