Genera una stringa alfanumerica casuale in Kotlin

1. Panoramica

In questo tutorial, discuteremo come generare una stringa alfanumerica casuale in Kotlin utilizzando tre diversi approcci: Java Random , Kotlin Random e Apache Commons Lang RandomStringUtils .

Quindi, concluderemo con uno sguardo a un approccio ad alte prestazioni.

2. Dipendenze

Prima di immergerci nel tutorial, aggiungiamo la dipendenza Apache Commons Lang nel nostro pom.xml:

 org.apache.commons commons-lang3 3.8.1 

Inoltre, possiamo impostare alcune costanti per riferimento successivo:

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

3. Java Random

Prima di tutto, diamo un'occhiata a come utilizzare Java Random per generare una stringa casuale .

In questo esempio, useremo ThreadLocalRandom che ha un'istanza Random per thread e protegge dalle contese:

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 questo esempio, otteniamo 10 caratteri alfanumerici casuali dal pool di caratteri generando i loro indici, quindi li uniamo per creare la stringa casuale .

ThreadLocalRandom è disponibile da JDK 7 . Potremmo invece usare java.util.Random . Ma se più thread utilizzano la stessa istanza di Random , lo stesso seme viene condiviso da più thread, causando conflitti tra i thread.

Tuttavia, ThreadLocalRandomRandom sono crittograficamente sicuri , poiché è possibile indovinare il valore successivo restituito dal generatore. Java fornisce java.security.SecureRandom notevolmente più lento per generare in modo sicuro un valore casuale.

4. Kotlin Random

Da Kotlin 1.3, kotlin.random.Random è disponibile come funzionalità multipiattaforma. Utilizza java.util.Random in JDK 6 e 7, ThreadLocalRandom in JDK 8+ e Math.random in Javascript.

Possiamo ottenere una stringa casuale con lo stesso approccio:

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

5. Apache Common Lang

Infine, se stiamo ancora utilizzando Kotlin, possiamo utilizzare le librerie Apache Common Lang per generare una stringa casuale :

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

In questo esempio, chiamiamo semplicemente RandomStringUtils.randomAlphanumeric per ottenere la nostra stringa con una lunghezza predefinita.

Dobbiamo notare che RandomStringUtils genera valori casuali utilizzando java.util.Random , che non è crittograficamente sicuro come discusso sopra. Quindi, in caso di generazione di un token o un valore protetto, possiamo utilizzare CryptoRandom in Apache Commons Crypto o SecureRandom di Java .

Abbiamo anche un tutorial su come generare una stringa casuale in Java per trattare questo argomento in modo più dettagliato.

6. Prestazioni

Un aspetto notevole di ciascuno di questi è che chiama il nostro generatore di numeri casuali STRING_LENGTH volte. Se stiamo creando molte stringhe o stringhe lunghe , questi approcci potrebbero essere troppo lenti. Con qualche sforzo in più, tuttavia, possiamo semplicemente chiamare una sequenza casuale di byte e quindi mapparli al nostro pool di caratteri:

@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) } 

Ciò che rende potente questo approccio è che, mentre eseguiamo ancora ricerche STRING_LENGTH nel nostro charPool , chiamiamo il nostro generatore casuale solo una volta. E, oltre ad essere più veloce, questo può anche ridurre la contesa tra i thread sulle istanze condivise.

7. Conclusione

In conclusione, abbiamo seguito tre approcci per generare una stringa alfanumerica casuale in Kotlin, esplorando le sfumature di ciascuno. Quindi, abbiamo cambiato marcia per esaminare una soluzione ad alte prestazioni che può essere riutilizzata per le API Kotlin e Java.

Come sempre, il codice può essere trovato su GitHub.