Generic Top

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> CHECK OUT THE COURSE

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 both 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 its outputs could be predicted by attackers.

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 places related to security.

8. 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.

Generic bottom

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> CHECK OUT THE COURSE
Comments are closed on this article!