在Kotlin中生成随机字母数字字符串的惯用法

bre*_*mri 22 kotlin

我可以在一定范围内生成一个随机的数字序列,如下所示:

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()
}
Run Code Online (Sandbox Code Playgroud)

然后我将不得不延伸List:

fun List<Char>.random() = this[Random().nextInt(this.size)]
Run Code Online (Sandbox Code Playgroud)

然后我可以这样做:

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("")
}
Run Code Online (Sandbox Code Playgroud)

但也许有更好的方法?

Hol*_*ndl 26

懒惰的人会这样做

java.util.UUID.randomUUID().toString()
Run Code Online (Sandbox Code Playgroud)

你不能在这里限制角色范围,但我想在很多情况下都很好.

  • 注意,Java 的 randomUUID() 实现将始终为您提供“4”作为 UUID 的“版本”部分,这就是为什么字符串中间总是有一个 4,这并不能使其完全随机。 (2认同)

Pau*_*cks 23

假设您有一组特定的源字符(source在此代码段中),您可以这样做:

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

这为outputStrLength = 10提供了类似"LYANFGNPNI"的字符串.

两个重要的部分是

  1. Random().ints(length, minValue, maxValue)它产生一个长度随机数的流,每个从minValuemaxValue-1,和
  2. asSequence()它将非大量有用的东西IntStream转化为更有用的东西Sequence<Int>.

  • 作为Kotlin newby,我一直在寻找这个解决方案 - 非常酷!但是我会使用`source.length`而不是`source.length - 1`,否则就不会看到Z.ints范围参数标记一个独占的上限. (2认同)
  • 好眼力.Java8 API设计人员非常有趣的想法,使这(几乎)成为Java中唯一的独占绑定描述参数... (2认同)

Whi*_*gel 20

Kotlin 1.3开始,您可以执行以下操作:

fun getRandomString(length: Int) : String {
    val allowedChars = "ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz"
    return (1..length)
        .map { allowedChars.random() }
        .joinToString("")
}
Run Code Online (Sandbox Code Playgroud)


And*_*icz 10

没有JDK8:

fun ClosedRange<Char>.randomString(length: Int) = 
    (1..length)
        .map { (Random().nextInt(endInclusive.toInt() - start.toInt()) + start.toInt()).toChar() }
        .joinToString("")
Run Code Online (Sandbox Code Playgroud)

用法:

('a'..'z').randomString(6)
Run Code Online (Sandbox Code Playgroud)


Jöc*_*ker 8

为定义的长度定义它:

val randomString = UUID.randomUUID().toString().substring(0,15)
Run Code Online (Sandbox Code Playgroud)

15字符数在哪里


Lou*_*lio 6

('A'..'z').map { it }.shuffled().subList(0, 4).joinToString("")
Run Code Online (Sandbox Code Playgroud)

  • 虽然这可能会回答作者的问题,但它缺少一些解释性词语和/或文档链接。如果没有一些短语,原始代码片段不是很有帮助。您可能还会发现 [如何写出好的答案](https://stackoverflow.com/help/how-to-answer) 非常有帮助。请编辑您的答案 - [来自评论](https://stackoverflow.com/review/low-quality-posts/21498067) (2认同)
  • 请注意,“('A'..'z')”还包括字符“[”、\、“]”、“^”、“_”和“\” (2认同)

The*_*tor 5

Collection.random()从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("")
Run Code Online (Sandbox Code Playgroud)


Fab*_*111 5

这个问题已经很老了,但我认为另一个很好的解决方案(应该从 Kotlin 1.3 开始工作)如下:

// Just a simpler way to create a List of characters, as seen in other answers
// You can achieve the same effect by declaring it as a String "ABCDEFG...56789"
val alphanumeric = ('A'..'Z') + ('a'..'z') + ('0'..'9')

fun generateAlphanumericString(length: Int) : String {
    // The buildString function will create a StringBuilder
    return buildString {
        // We will repeat length times and will append a random character each time
        // This roughly matches how you would do it in plain Java
        repeat(length) { append(alphanumeric.random()) }
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 5

基于 Fabb111 的答案

fun randomString(length: Int): String =
    buildString {
        repeat(length) {
            append((0 until 36).random().toString(36))
        }
    }
Run Code Online (Sandbox Code Playgroud)

可以使用 . 数字将数字转换为不同的基数Int.toString(Int)
Base 36 是包含所有字母数字字符的数字系统