Zufallszahlengenerierung in Android mit Kotlin: Was steckt unter der Haube?

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Wie bringt man Android dazu, „Würfel zu werfen“? Wir analysieren die Zufallszahlengenerierung mit Kotlin

\n\n

Haben Sie sich jemals gefragt, wie Ihr Telefon eine Zufallszahl „auswählt“? Es scheint eine einfache Aufgabe zu sein – eine zufällige ganze Zahl von 5 bis 10 zu erhalten. Aber unter der Haube von Android und Kotlin verbirgt sich ein ganzer Mechanismus, von dem nicht nur der Komfort, sondern auch die Sicherheit Ihrer App abhängt. Kein Wunder, dass die Frage „How can I generate random number in specific range in Android?“ Tausende von Aufrufen auf Stack Overflow gesammelt hat. Wir geben nicht nur eine fertige Antwort – wir werfen einen Blick in die Quellen und analysieren, was tatsächlich passiert.

\n\n

In diesem Artikel erfahren Sie:

\n
    \n
  • Wie man in Kotlin korrekt eine Zufallszahl in einem bestimmten Bereich generiert.
  • \n
  • Worin sich kotlin.random.Random, java.util.Random und SecureRandom unterscheiden.
  • \n
  • Warum für Glücksspiele eine Klasse benötigt wird und für die Passwortgenerierung eine andere.
  • \n
  • Wie man typische Fehler vermeidet, die „Zufälligkeit“ in Vorhersagbarkeit verwandeln.
  • \n
\n\n

Los geht‘s!

\n\n

Der Klassiker: Random in Kotlin (und warum das nicht immer richtig ist)

\n\n

Der offensichtlichste Weg ist die Verwendung von kotlin.random.Random. Es ist direkt in die Sprache integriert und funktioniert sofort. So sieht die Generierung einer Zufallszahl von 0 bis 100 (einschließlich) aus:

\n\n
import kotlin.random.Random\n\nfun main() {\n    val randomNumber = Random.nextInt(0, 101) // von 0 bis 100 einschließlich\n    println("Zufallszahl: $randomNumber")\n}
\n\n

Alles einfach. Aber werfen wir einen Blick unter die Haube. Random.nextInt(from, until) verwendet intern java.util.Random (auf der JVM-Plattform). Und dieser wiederum generiert Zahlen mit einem linearen Kongruenzgenerator (LCG). Die Formel ist einfach:

\n\n

new_seed = (old_seed * A + C) mod M

\n\n

Wobei A, C und M Konstanten sind. Das ist schnell, aber nicht kryptographisch sicher. Wenn ein Angreifer nur ein paar Zahlen kennt, kann er den Seed wiederherstellen und alle nachfolgenden vorhersagen.

\n\n

Wann verwenden: Für Spiele (nicht um Geld), zufällige Auswahl eines Elements aus einer Liste, Mischen von Karten in einer normalen App.

\n\n

Fortgeschrittene Stufe: ThreadLocalRandom für Multithreading

\n\n

Wenn Ihre App intensiv Coroutinen oder Multithreading nutzt, kann der normale Random zum Engpass werden. Jeder Aufruf von nextInt() wird synchronisiert, um Race Conditions zu vermeiden. Die Lösung ist ThreadLocalRandom aus 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

Diese Klasse weist jedem Thread eine separate Instanz von Random zu. Synchronisation ist nicht erforderlich – jeder Thread arbeitet mit seinem eigenen Generator. In der Praxis führt dies zu einer Leistungssteigerung in Multithreading-Szenarien.

\n\n

Sicherheit geht vor: SecureRandom

\n\n

Stellen Sie sich nun vor, Sie generieren ein Einmalpasswort (OTP) oder einen Token für die Zugriffswiederherstellung. Die Verwendung des normalen Random wäre ein Verbrechen. Hier kommt SecureRandom ins Spiel:

\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 sammelt Entropie aus Quellen des Betriebssystems: Mikrofongeräusche, Tastendruck-Timings (im Emulator aus der Datei /dev/random oder /dev/urandom). Dies macht es unvorhersehbar. Dafür muss man jedoch mit Geschwindigkeit bezahlen – es kann um ein Vielfaches langsamer sein als das normale Random.

\n\n

Wichtig: Auf Android S

Blogs

Buchempfehlungen