Erzeugen Sie eine zufällige alphanumerische Zeichenfolge in Kotlin

Generieren Sie eine zufällige alphanumerische Zeichenfolge in Kotlin

1. Überblick

In diesem Tutorial wird erläutert, wie in Kotlin zufällige alphanumerischeString mithilfe von drei verschiedenen Ansätzen generiert werden: JavaRandom, KotlinRandom und Apache Commons LangRandomStringUtils.

Anschließend werden wir uns mit einem Hochleistungsansatz befassen.

2. Abhängigkeiten

Bevor wir uns mit dem Tutorial befassen, fügen wir dieApache Commons Lang dependency zu unserenpom.xml: hinzu


    org.apache.commons
    commons-lang3
    3.8.1

Zusätzlich können wir einige Konstanten für eine spätere Bezugnahme einrichten:

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

3. JavaRandom

Schauen wir uns zunächst an, wieuse Java Random to generate a random String.

In diesem Beispiel verwenden wirThreadLocalRandom mit einerRandom-Instanz pro Thread und Schutz vor Konflikten:

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 werden wirgetting 10 random alphanumeric characters from character pool by generating their indexes, zusammenfügen, um die zufälligenString. zu erstellen

ThreadLocalRandom ist verfügbar, da JDK 7Wir könnten stattdessenjava.util.Random verwenden. But if multiple threads use the same instance of Random, the same seed is shared by multiple threads, causing thread contention.

neither ThreadLocalRandom nor Random are cryptographically secure, da der nächste vom Generator zurückgegebene Wert erraten werden kann. Java liefert die deutlich langsamerenjava.security.SecureRandom, um einen zufälligen Wert sicher zu generieren.

4. KotlinRandom

Ab Kotlin 1.3 istkotlin.random.Random als Multiplattform-Funktion verfügbar. Es werdenjava.util.Random in JDK 6 und 7,ThreadLocalRandom in JDK 8+ undMath.random in Javascript verwendet.

Mit demselben Ansatz können wir zufälligeString 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 wirmake use of Apache Common Lang libraries to generate a random String:

@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 einfachRandomStringUtils.randomAlphanumeric auf, um unsereString mit einer vordefinierten Länge zu erhalten.

Wir sollten beachten, dassRandomStringUtils zufällige Werte erzeugen, indemjava.util.Random verwendet werden, was nicht kryptografisch sicher ist, wie oben erläutert. So in case of generating a secured token or value, we can use CryptoRandom in Apache Commons Crypto or Java’s SecureRandom.

Wir haben auch ein Tutorial überhow to generate a random String in Java, um dieses Thema ausführlicher zu behandeln.

6. Performance

Ein bemerkenswerter Aspekt von jedem von diesen ist, dass es unseren ZufallszahlengeneratorSTRING_LENGTH times aufruft. Wenn wir vieleStrings oder langeStrings, erstellen, sind diese Ansätze möglicherweise zu langsam. With some extra effort 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.get((bytes[i] and 0xFF.toByte() and (charPool.size-1).toByte()).toInt())
    }.joinToString("")

    assert(randomString.matches(Regex(ALPHANUMERIC_REGEX)))
    assertEquals(STRING_LENGTH, randomString.length)
}

Was diesen Ansatz leistungsfähig macht, ist, dasswhile we still do STRING_LENGTH lookups to our charPool, we only call on our random generator once.. Abgesehen davon, dass er schneller ist, kann dies auch Thread-Konflikte auf gemeinsam genutzten Instanzen reduzieren.

Beachten Sie außerdem, dassbytes[i] and 0xFF.toByte() and charPool.size.toByte() zwar erweitert aussehen kann, dies jedoch nur eine Möglichkeit ist, um sicherzustellen, dass die zufälligen Bytes zwischenundcharPool.size() liegen.

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 neu verwendet werden kann.

Wie immer kann der Codeover on GitHub gefunden werden.