Geração de números aleatórios no Android com Kotlin: o que está por baixo dos panos?

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Como fazer o Android "lançar dados"? Analisando a geração de números aleatórios em Kotlin

\n\n

Você já se perguntou como seu telefone "escolhe" um número aleatório? Parece uma tarefa simples — obter um inteiro aleatório de 5 a 10. Mas por baixo dos panos do Android e Kotlin, esconde-se todo um mecanismo do qual depende não apenas a conveniência, mas também a segurança do seu aplicativo. Não é surpresa que a pergunta "How can I generate random number in specific range in Android?" tenha milhares de visualizações no Stack Overflow. Não vamos apenas dar uma resposta pronta — vamos mergulhar nos fontes e entender o que realmente acontece.

\n\n

Neste artigo, você aprenderá:

\n
    \n
  • Como gerar corretamente um número aleatório em um intervalo específico em Kotlin.
  • \n
  • Quais as diferenças entre kotlin.random.Random, java.util.Random e SecureRandom.
  • \n
  • Por que para jogos de azar é necessária uma classe, e para geração de senhas, outra.
  • \n
  • Como evitar erros típicos que transformam "aleatoriedade" em previsibilidade.
  • \n
\n\n

Vamos nessa!

\n\n

Clássico do gênero: Random em Kotlin (e por que nem sempre é o correto)

\n\n

A maneira mais óbvia é usar kotlin.random.Random. Ele está embutido diretamente na linguagem e funciona de fábrica. Veja como é a geração de um número aleatório de 0 a 100 (inclusive):

\n\n
import kotlin.random.Random\n\nfun main() {\n    val randomNumber = Random.nextInt(0, 101) // de 0 a 100 inclusive\n    println("Número aleatório: $randomNumber")\n}
\n\n

Tudo simples. Mas vamos olhar por baixo dos panos. Random.nextInt(from, until) internamente usa java.util.Random (na plataforma JVM). E este, por sua vez, gera números usando um gerador linear congruencial (LCG). A fórmula é simples:

\n\n

new_seed = (old_seed * A + C) mod M

\n\n

Onde A, C e M são constantes. Isso é rápido, mas não é criptograficamente seguro. Se um invasor descobrir alguns números, ele pode recuperar a seed e prever todos os subsequentes.

\n\n

Quando usar: Para jogos (que não envolvam dinheiro), seleção aleatória de um elemento de uma lista, embaralhamento de cartas em um aplicativo comum.

\n\n

Nível avançado: ThreadLocalRandom para multithreading

\n\n

Se seu aplicativo usa ativamente coroutines ou multithreading, o Random comum pode se tornar um gargalo. Cada chamada a nextInt() é sincronizada para evitar condições de corrida. A solução é ThreadLocalRandom do Java:

\n\n
import java.util.concurrent.ThreadLocalRandom\n\nfun getRandomInRange(min: Int, max: Int): Int {\n    return ThreadLocalRandom.current().nextInt(min, max + 1)\n}
\n\n

Esta classe aloca uma instância separada de Random para cada thread. A sincronização não é necessária — cada thread trabalha com seu próprio gerador. Na prática, isso proporciona um ganho de desempenho em cenários multithread.

\n\n

Segurança acima de tudo: SecureRandom

\n\n

Agora imagine que você está gerando uma senha de uso único (OTP) ou um token para recuperação de acesso. Usar o Random comum é um crime. É aqui que entra o SecureRandom:

\n\n
import java.security.SecureRandom\n\nfun generateSecureCode(length: Int): String {\n    val secureRandom = SecureRandom()\n    val digits = "0123456789"\n    return (1..length)\n        .map { digits[secureRandom.nextInt(digits.length)] }\n        .joinToString("")\n}
\n\n

O SecureRandom coleta entropia de fontes do sistema operacional: ruídos do microfone, temporizações de pressionamento de teclas (no emulador, do arquivo /dev/random ou /dev/urandom). Isso o torna imprevisível. Mas isso tem um custo em velocidade — ele pode ser dezenas de vezes mais lento que o Random comum.

\n\n

Importante: No Android, o S

Blogs

Book Recommendations