Génération de nombres aléatoires dans Android avec Kotlin : qu'est-ce qui se cache sous le capot ?

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Comment faire « jeter les dés » à Android ? Décryptage de la génération de nombres aléatoires avec Kotlin

\n\n

Avez-vous déjà réfléchi à la façon dont votre téléphone « choisit » un nombre aléatoire ? Apparemment une tâche simple — obtenir un entier aléatoire entre 5 et 10. Mais sous le capot d'Android et de Kotlin se cache tout un mécanisme, dont dépendent non seulement la commodité, mais aussi la sécurité de votre application. Il n'est pas surprenant que la question « How can I generate random number in specific range in Android? » ait recueilli des milliers de vues sur Stack Overflow. Nous ne nous contenterons pas de donner une réponse toute faite — nous allons jeter un coup d'œil dans les sources et comprendre ce qui se passe réellement.

\n\n

Dans cet article, vous apprendrez :

\n
    \n
  • Comment générer correctement un nombre aléatoire dans une plage donnée avec Kotlin.
  • \n
  • En quoi kotlin.random.Random, java.util.Random et SecureRandom diffèrent.
  • \n
  • Pourquoi les jeux de hasard nécessitent une classe, et la génération de mots de passe une autre.
  • \n
  • Comment éviter les erreurs typiques qui transforment le « hasard » en prévisibilité.
  • \n
\n\n

C'est parti !

\n\n

Le classique du genre : Random en Kotlin (et pourquoi ce n'est pas toujours correct)

\n\n

La méthode la plus évidente est d'utiliser kotlin.random.Random. Il est intégré directement dans le langage et fonctionne prêt à l'emploi. Voici à quoi ressemble la génération d'un nombre aléatoire de 0 à 100 (inclus) :

\n\n
import kotlin.random.Random\n\nfun main() {\n    val randomNumber = Random.nextInt(0, 101) // de 0 à 100 inclus\n    println("Nombre aléatoire : $randomNumber")\n}
\n\n

Tout est simple. Mais regardons sous le capot. Random.nextInt(from, until) utilise en interne java.util.Random (sur la plateforme JVM). Et celui-ci, à son tour, génère des nombres à l'aide d'un générateur linéaire congruentiel (LCG). La formule est simple :

\n\n

new_seed = (old_seed * A + C) mod M

\n\n

Où A, C et M sont des constantes. C'est rapide, mais pas cryptographiquement sûr. Si un attaquant découvre ne serait-ce que quelques nombres, il peut reconstituer la seed et prédire tous les suivants.

\n\n

Quand l'utiliser : Pour les jeux (pas d'argent), la sélection aléatoire d'un élément dans une liste, le mélange de cartes dans une application ordinaire.

\n\n

Niveau avancé : ThreadLocalRandom pour le multithreading

\n\n

Si votre application utilise activement les coroutines ou le multithreading, un Random ordinaire peut devenir un goulot d'étranglement. Chaque appel à nextInt() est synchronisé pour éviter les conditions de concurrence. La solution — ThreadLocalRandom de 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

Cette classe alloue une instance distincte de Random pour chaque thread. Aucune synchronisation n'est nécessaire — chaque thread travaille avec son propre générateur. En pratique, cela offre un gain de performance dans les scénarios multithreads.

\n\n

La sécurité avant tout : SecureRandom

\n\n

Imaginez maintenant que vous générez un mot de passe à usage unique (OTP) ou un jeton pour la récupération d'accès. Utiliser un Random ordinaire serait un crime. C'est là qu'intervient 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

SecureRandom collecte l'entropie à partir des sources du système d'exploitation : bruits du microphone, temporisations des frappes au clavier (dans l'émulateur — à partir du fichier /dev/random ou /dev/urandom). Cela le rend imprévisible. Mais cela se paie en vitesse — il peut être des dizaines de fois plus lent qu'un Random ordinaire.

\n\n

Important : Sur Android, S

Blogs

Book Recommendations