An idiomatic way to generate a random alphanumeric string in Kotlin

I can create a random sequence of numbers in a specific range, for example:

fun ClosedRange<Int>.random() = Random().nextInt(endInclusive - start) + start fun generateRandomNumberList(len: Int, low: Int = 0, high: Int = 255): List<Int> { (0..len-1).map { (low..high).random() }.toList() } 

Then I have to stretch the List with

 fun List<Char>.random() = this[Random().nextInt(this.size)] 

Then I can do:

 fun generateRandomString(len: Int = 15): String{ val alphanumerics = CharArray(26) { it -> (it + 97).toChar() }.toSet() .union(CharArray(9) { it -> (it + 48).toChar() }.toSet()) return (0..len-1).map { alphanumerics.toList().random() }.joinToString("") } 

But maybe the best way?

+19
source share
11 answers

Assuming you have a specific set of source characters ( source in this snippet), you can do this:

 val source = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" java.util.Random().ints(outputStrLength, 0, source.length) .asSequence() .map(source::get) .joinToString("") 

Which gives strings like "LYANFGNPNI" for outputStrLength = 10.

Two important bits

  1. Random().ints(length, minValue, maxValue) which creates a stream of random numbers from minValue to maxValue-1 in length, and
  2. asSequence() which converts a not very useful IntStream to a much more useful Sequence<Int> .
+24
source

Lazy people just did

 java.util.UUID.randomUUID().toString() 

You cannot limit the range of characters here, but I think this is normal in many situations.

+18
source

Starting with Kotlin 1.3 you can do this:

 fun getRandomString(length: Int) : String { val allowedChars = "ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz" return (1..length) .map { allowedChars.random() } .joinToString("") } 
+10
source

Without JDK8:

 fun ClosedRange<Char>.randomString(lenght: Int) = (1..lenght) .map { (Random().nextInt(endInclusive.toInt() - start.toInt()) + start.toInt()).toChar() } .joinToString("") 

using:

 ('a'..'z').randomString(6) 
+8
source
 ('A'..'z').map { it }.shuffled().subList(0, 4).joinToString("") 
+3
source

Using Kotlin 1.3 :

This method uses the input of the desired string length of the desired desiredStrLength as an integer and returns a random alphanumeric string of the desired string length.

 fun randomAlphaNumericString(desiredStrLength: Int): String { val charPool: List<Char> = ('a'..'z') + ('A'..'Z') + ('0'..'9') return (1..desiredStrLength) .map{ kotlin.random.Random.nextInt(0, charPool.size) } .map(charPool::get) .joinToString("") } 

If you prefer an unknown length to alphanumeric (or at least a long enough string, for example 36 in my example below), this method can be used:

 fun randomAlphanumericString(): String { val charPool: List<Char> = ('a'..'z') + ('A'..'Z') + ('0'..'9') val outputStrLength = (1..36).shuffled().first() return (1..outputStrLength) .map{ kotlin.random.Random.nextInt(0, charPool.size) } .map(charPool::get) .joinToString("") } 
+3
source

Or use the coroutine API for the true spirit of Kotlin:

 buildSequence { val r = Random(); while(true) yield(r.nextInt(24)) } .take(10) .map{(it+ 65).toChar()} .joinToString("") 
+2
source

Based on Paul Hicks answer, I wanted to use a custom string as input. In my case, uppercase and lowercase alphanumeric characters. Random().ints(...) also did not work for me, since using it required API level 24 on Android.

Here's how I do it with the Kotlin Random abstract class:

 import kotlin.random.Random object IdHelper { private val ALPHA_NUMERIC = ('0'..'9') + ('A'..'Z') + ('a'..'z') private const val LENGTH = 20 fun generateId(): String { return List(LENGTH) { Random.nextInt(0, ALPHA_NUMERIC.size) } .map { ALPHA_NUMERIC[it] } .joinToString(separator = "") } } 

The process and how it works is similar to many other answers already posted here:

  1. Create a list of LENGTH length numbers that correspond to the source string index values, which in this case is ALPHA_NUMERIC
  2. Match these numbers with the original string, converting each numerical index into a character value.
  3. Convert the resulting list of characters to a string by concatenating them with an empty string as a delimiter character.
  4. Return the resulting string.

Easy to use, just call it as a static function: IdHelper.generateId()

+1
source
 fun randomAlphaNumericString(@IntRange(from = 1, to = 62) lenght: Int): String { val alphaNumeric = ('a'..'z') + ('A'..'Z') + ('0'..'9') return alphaNumeric.shuffled().take(lenght).joinToString("") } 
+1
source

The best way, I think:

 fun generateID(size: Int): String { val source = "A1BCDEF4G0H8IJKLM7NOPQ3RST9UVWX52YZab1cd60ef2ghij3klmn49opq5rst6uvw7xyz8" return (source).map { it }.shuffled().subList(0, size).joinToString("") } 
0
source

Using Collection.random() from Kotlin 1.3:

 // Descriptive alphabet using three CharRange objects, concatenated val alphabet: List<Char> = ('a'..'z') + ('A'..'Z') + ('0'..'9') // Build list from 20 random samples from the alphabet, // and convert it to a string using "" as element separator val randomString: String = List(20) { alphabet.random() }.joinToString("") 
0
source

Source: https://habr.com/ru/post/1272898/


All Articles