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

时间:2017-10-26 00:07:44

标签: 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()
}

然后我必须将List扩展为:

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

然后我可以做:

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("")
}

但也许有更好的方法?

15 个答案:

答案 0 :(得分:24)

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

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

它提供了像&#34; LYANFGNPNI&#34;对于outputStrLength = 10。

两个重要的部分是

  1. Random().ints(length, minValue, maxValue)生成一个长度随机数的流,每个 minValue maxValue-1
  2. asSequence()可将非大量有用的IntStream转换为更有用的Sequence<Int>

答案 1 :(得分:18)

懒惰的人会做

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

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

答案 2 :(得分:8)

没有JDK8:

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

用法:

('a'..'z').randomString(6)

答案 3 :(得分:7)

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

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

答案 4 :(得分:3)

要为定义的长度定义它:

val randomString = UUID.randomUUID().toString().substring(0,15)

其中15是字符数

答案 5 :(得分:2)

或者使用协程API来获得真正的Kotlin精神:

e = e.replace("'",'"')

答案 6 :(得分:1)

('A'..'z').map { it }.shuffled().subList(0, 4).joinToString("")

答案 7 :(得分:1)

基于Paul Hicks的答案,我想要一个自定义字符串作为输入。就我而言,是大写和小写字母数字字符。 Random().ints(...)也不适用于我,因为它需要Android上的API级别为24才能使用。

这就是我对Kotlin的Random抽象类的处理方式:

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 = "")
    }
}

此过程及其工作方式与此处已经发布的许多其他答案类似:

  1. 生成一个长度为LENGTH的数字列表,这些数字与源字符串的索引值相对应,在本例中为ALPHA_NUMERIC
  2. 将这些数字映射到源字符串,将每个数字索引转换为字符值
  3. 将生成的字符列表转换为字符串,并使用空字符串作为分隔符将它们连接起来。
  4. 返回结果字符串。

用法很简单,只需像静态函数一样调用它即可:IdHelper.generateId()

答案 8 :(得分:1)

使用 Kotlin 1.3

此方法使用所需字符串长度desiredStrLength的输入作为整数,并返回所需字符串长度的随机字母数字字符串。

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("")
}

如果您希望使用未知的字母数字长度(或者在下面的示例中至少要像36这样长的字符串长度),则可以使用以下方法:

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("")
}

答案 9 :(得分:1)

var chartData = [{
  date: '12/5/2018',
  visits: 100
}, {
  date: '12/6/2018',
  visits: 200
}, {
  date: '12/8/2018',
  visits: 170
}, {
  date: '12/10/2018',
  visits: 320
}];

var chart = AmCharts.makeChart("chartdiv", {
  "theme": "black",
  "type": "serial",
  "dataProvider": chartData,
  "valueAxes": [{
    "id": "v1",
    "axisAlpha": 0.1
  }],
  "graphs": [{
    "useNegativeColorIfDown": true,
    "balloonText": "[[category]]<br><b>value: [[value]]</b>",
    "bullet": "round",
    "valueField": "visits"
  }],
  "chartCursor": {
    "valueLineEnabled": true,
    "valueLineBalloonEnabled": true
  },
  "categoryField": "date",
  "categoryAxis": {
    "parseDates": true,
  },
  "export": {
    "enabled": true,
    "backgroundColor": '#3B3B3C',
  }
});

答案 10 :(得分:1)

使用Kotlin 1.3中的Collection.random()

// 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("")

答案 11 :(得分:0)

我认为的最好方式:

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

答案 12 :(得分:0)

我使用以下代码生成随机单词和句子。

val alphabet: List<Char> = ('a'..'z') + ('A'..'Z') + ('0'..'9')

val randomWord: String = List((1..10).random()) { alphabet.random() }.joinToString("")

val randomSentence: String = (1..(1..10).random()).joinToString(" ") { List((1..10).random()) { alphabet.random() }.joinToString("") }

答案 13 :(得分:0)

这个问题已经很老了,但我认为另一个很好的解决方案(应该从 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()) }
    }
}

答案 14 :(得分:0)

您可以使用 apache-commons-lang3

中的 RandomStringUtils.randomAlphanumeric(min: Int, max: Int) -> String