Generieren Sie eine zufällige alphanumerische Zeichenfolge in Kotlin

1. Übersicht

In diesem Tutorial wird erläutert, wie Sie in Kotlin mithilfe von drei verschiedenen Ansätzen einen zufälligen alphanumerischen String generieren : Java Random , Kotlin Random und Apache Commons Lang RandomStringUtils .

Anschließend werden wir uns einen Hochleistungsansatz ansehen.

2. Abhängigkeiten

Bevor wir uns mit dem Tutorial befassen, fügen wir die Apache Commons Lang-Abhängigkeit in unsere pom.xml ein:

 org.apache.commons commons-lang3 3.8.1 

Darüber hinaus können wir einige Konstanten zur späteren Bezugnahme einrichten:

const val STRING_LENGTH = 10; const val ALPHANUMERIC_REGEX = "[a-zA-Z0-9]+"; 

3. Java Random

Schauen wir uns zunächst an, wie Sie mit Java Random einen zufälligen String generieren .

In diesem Beispiel verwenden wir ThreadLocalRandom, das eine zufällige Instanz pro Thread enthält und vor Konflikten schützt :

private val charPool : List = ('a'..'z') + ('A'..'Z') + ('0'..'9') @Test fun givenAStringLength_whenUsingJava_thenReturnAlphanumericString() { val randomString = ThreadLocalRandom.current() .ints(STRING_LENGTH.toLong(), 0, charPool.size) .asSequence() .map(charPool::get) .joinToString("") assert(randomString.matches(Regex(ALPHANUMERIC_REGEX))); assertEquals(STRING_LENGTH, randomString.length); }

In diesem Beispiel erhalten wir 10 zufällige alphanumerische Zeichen aus dem Zeichenpool, indem wir ihre Indizes generieren und sie dann zusammenfügen, um die zufällige Zeichenfolge zu erstellen .

ThreadLocalRandom ist seit JDK 7 verfügbar . Wir könnten stattdessen java.util.Random verwenden. Wenn jedoch mehrere Threads dieselbe Instanz von Random verwenden , wird derselbe Startwert von mehreren Threads gemeinsam genutzt, was zu Thread-Konflikten führt.

Doch weder ThreadLocalRandom noch Zufall sind kryptographisch zu sichern , wie es möglich ist , den nächsten Wert aus dem Generator zurückgeführt zu erraten. Java bietet das deutlich langsamere java.security.SecureRandom , um einen zufälligen Wert sicher zu generieren.

4. Kotlin Random

Ab Kotlin 1.3 ist kotlin.random.Random als Multiplattform-Funktion verfügbar. Es verwendet java.util.Random in JDK 6 und 7, ThreadLocalRandom in JDK 8+ und Math.random in Javascript.

Wir können einen zufälligen String mit dem gleichen Ansatz erhalten:

val randomString = (1..STRING_LENGTH) .map { i -> kotlin.random.Random.nextInt(0, charPool.size) } .map(charPool::get) .joinToString("");

5. Apache Common Lang

Wenn wir Kotlin noch verwenden, können wir Apache Common Lang-Bibliotheken verwenden, um einen zufälligen String zu generieren :

@Test fun givenAStringLength_whenUsingApacheCommon_thenReturnAlphanumericString() { val randomString = RandomStringUtils.randomAlphanumeric(STRING_LENGTH); assert(randomString.matches(Regex(ALPHANUMERIC_REGEX))); assertEquals(STRING_LENGTH, randomString.length); }

In diesem Beispiel rufen wir einfach RandomStringUtils.randomAlphanumeric auf, um unseren String mit einer vordefinierten Länge abzurufen .

Wir sollten beachten, dass RandomStringUtils mithilfe von java.util.Random zufällige Werte generieren , was nicht kryptografisch sicher ist, wie oben erläutert. Im Falle der Generierung eines gesicherten Tokens oder Werts können wir CryptoRandom in Apache Commons Crypto oder Javas SecureRandom verwenden.

Wir haben ein Tutorial zum Generieren eines zufälligen Strings in Java, um dieses Thema ausführlicher zu behandeln.

6. Leistung

Ein bemerkenswerter Aspekt von jedem von diesen ist, dass es unseren Zufallszahlengenerator STRING_LENGTH mal aufruft . Wenn wir viele Strings oder lange Strings erstellen , sind diese Ansätze möglicherweise zu langsam. Mit etwas mehr Aufwand können wir jedoch einfach eine zufällige Folge von Bytes aufrufen und sie dann unserem Zeichenpool zuordnen:

@Test fun givenAStringLength_whenUsingRandomForBytes_thenReturnAlphanumericString() { val random = SecureRandom() val bytes = ByteArray(STRING_LENGTH) random.nextBytes(bytes) val randomString = (0..bytes.size - 1) .map { i -> charPool[random.nextInt(charPool.size)] }.joinToString("") assert(randomString.matches(Regex(ALPHANUMERIC_REGEX))) assertEquals(STRING_LENGTH, randomString.length) } 

Was diesen Ansatz so leistungsfähig macht, ist, dass wir unseren Zufallsgenerator nur einmal aufrufen , während wir noch STRING_LENGTH-Suchvorgänge für unseren charPool durchführen . Dies ist nicht nur schneller, sondern kann auch die Thread-Konkurrenz auf gemeinsam genutzten Instanzen verringern.

7. Fazit

Zusammenfassend haben wir drei Ansätze durchlaufen, um eine zufällige alphanumerische Zeichenfolge in Kotlin zu generieren und die Nuancen der einzelnen zu untersuchen. Anschließend haben wir den Gang gewechselt, um eine Hochleistungslösung zu untersuchen, die für die Kotlin- und Java-APIs verwendet werden kann.

Wie immer ist der Code auf GitHub zu finden.