Как получить случайное число в Kotlin: полный гайд с примерами

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Случайность — это не хаос: как Kotlin решает задачу из Stack Overflow

Каждый разработчик хотя бы раз в жизни писал код для генерации случайного числа. Казалось бы, что может быть проще? Но когда этот вопрос задают на Stack Overflow (а вопрос "How can I get a random number in Kotlin?" собирает тысячи просмотров), становится ясно: подводных камней больше, чем кажется. Особенно если вы переходите с Java или Python.

В этой статье мы разберем генерацию случайных чисел в Kotlin от простых до продвинутых техник. Вы узнаете, как получить случайное целое, дробное число, как задать диапазон и даже как сгенерировать криптостойкий random для безопасности. Поехали!

Основы: Random в Kotlin

В Kotlin нет своего отдельного класса для random — он использует мощный java.util.Random из Java, но с гораздо более удобным синтаксисом. Благодаря функциям-расширениям, написать Kotlin random код можно буквально в одну строку.

Самый простой способ: Random.nextInt()

Если вам нужно просто случайное целое число (от 0 до максимального значения Int), используйте:

import kotlin.random.Random

fun main() {
    val randomNumber = Random.nextInt()
    println("Случайное число: $randomNumber")
}

Каждый запуск будет выдавать новое значение. Но чаще всего нам нужно ограничить диапазон. Для этого есть перегруженная версия:

val fromZeroToTen = Random.nextInt(10)   // 0..9
val fromFiveToFifteen = Random.nextInt(5, 15) // 5..14
Важно: В Kotlin, как и в Java, верхняя граница не включается. Random.nextInt(10) вернет число от 0 до 9.

Дробные числа: Random.nextDouble() и Random.nextFloat()

Для генерации случайного float в Kotlin или double используйте:

val randomDouble = Random.nextDouble()   // 0.0..1.0
val randomFloat = Random.nextFloat()     // 0.0..1.0

// С диапазоном:
val doubleInRange = Random.nextDouble(10.0, 20.0) // 10.0..20.0

Обратите внимание: nextFloat() не поддерживает диапазон — только nextDouble(). Если нужен float в диапазоне, конвертируйте:

val customFloat = Random.nextDouble(1.5, 5.5).toFloat()

Генерация случайных чисел в диапазоне: практические примеры

Чаще всего в реальных проектах требуется случайное число в заданном диапазоне Kotlin. Давайте разберем самые популярные сценарии.

Случайное целое от 1 до 100 (включительно)

Чтобы включить верхнюю границу, просто прибавьте 1:

val diceRoll = Random.nextInt(1, 7)  // 1..6 (как игральная кость)
val lottery = Random.nextInt(1, 101) // 1..100

Случайный индекс массива или списка

Одна из самых частых задач — получить случайный элемент из коллекции:

val colors = listOf("Красный", "Синий", "Зеленый", "Желтый")
val randomColor = colors[Random.nextInt(colors.size)]
println("Случайный цвет: $randomColor")

Но в Kotlin есть еще более элегантный способ — функция random():

val randomColor = colors.random()
println("Случайный цвет: $randomColor")

Под капотом она делает то же самое, но код становится чище.

Случайное число с шагом

Иногда нужно генерировать числа, кратные определенному значению. Например, четные числа от 0 до 100:

fun randomEven(max: Int): Int {
    val half = max / 2
    return Random.nextInt(0, half + 1) * 2
}

println(randomEven(100)) // 0, 2, 4, ..., 100

Продвинутые техники: последовательности и криптостойкость

Случайная последовательность чисел

Если нужно сгенерировать список случайных чисел, используйте generateSequence:

val randomSequence = generateSequence { Random.nextInt(1, 100) }
val tenRandomNumbers = randomSequence.take(10).toList()
println(tenRandomNumbers) // [23, 87, 5, 42, ...]

Этот подход ленивый — числа генерируются только когда вы их запрашиваете. Отлично подходит для бесконечных потоков данных.

SecureRandom для безопасности

Если вы работаете с паролями, токенами или любыми данными, где важна криптостойкая случайность, стандартный Random не подойдет. Он предсказуем. Используйте java.security.SecureRandom:

import java.security.SecureRandom

fun generateSecureToken(length: Int): String {
    val secureRandom = SecureRandom()
    val chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
    return (1..length)
        .map { chars[secureRandom.nextInt(chars.length)] }
        .joinToString("")
}

println(generateSecureToken(16)) // "aB3xK9mZ..."

Обратите внимание: SecureRandom медленнее, но он использует энтропию системы (шум оборудования, время между нажатиями клавиш) и не поддается взлому.

Генерация случайного булева значения

Иногда нужно просто "подбросить монетку":

val coinFlip = Random.nextBoolean()
println(if (coinFlip) "Орел" else "Решка")

Подводные камни и частые ошибки

Даже опытные разработчики иногда спотыкаются на случайных числах в Kotlin. Вот 3 типичные ошибки:

1. Забыл про seed

По умолчанию Random инициализируется случайным seed'ом. Но если вы создадите свой экземпляр с одинаковым seed, последовательность будет повторяться:

val fixedRandom = Random(42)
println(fixedRandom.nextInt(100)) // Всегда одно и то же!
println(fixedRandom.nextInt(100)) // И это тоже!

Это может быть полезно для тестов (детерминированное поведение), но в продакшене — катастрофа.

2. Путаница с границами

Помните: Random.nextInt(5, 10) дает 5..9, а не 5..10. Если нужно включительно — используйте Random.nextInt(5, 11).

3. Random в многопоточном окружении

Стандартный kotlin.random.Random потокобезопасен, но производительность может страдать. Для высоконагруженных систем используйте ThreadLocalRandom из Java:

import java.util.concurrent.ThreadLocalRandom

val threadSafeRandom = ThreadLocalRandom.current().nextInt(1,                

Блоги

Рекомендаций по книгам