Kotlinで乱数を取得する

Kotlinで乱数を取得する

1. 前書き

この短いチュートリアルでは、Kotlinを使用して乱数を生成する方法を示します。

2. java.lang.Mathを使用した乱数

Kotlinで乱数を生成する最も簡単な方法は、java.lang.Mathを使用することです。 以下の例では、0〜1のランダムな倍精度数が生成されます。

@Test
fun whenRandomNumberWithJavaUtilMath_thenResultIsBetween0And1() {
    val randomNumber = Math.random()
    assertTrue { randomNumber >= 0 }
    assertTrue { randomNumber < 1 }
}

3. ThreadLocalRandomを使用した乱数

java.util.concurrent.ThreadLocalRandomを使用して、ランダムなdouble、integer、またはlong値を生成することもできます。 Integer and long values generated this way can be both positive or negative

ThreadLocalRandom is thread-safe and provides better performance in a multithreaded environmentは、スレッドごとに個別のRandomオブジェクトを提供し、スレッド間の競合を減らすためです。

@Test
fun whenRandomNumberWithJavaThreadLocalRandom_thenResultsInDefaultRanges() {
    val randomDouble = ThreadLocalRandom.current().nextDouble()
    val randomInteger = ThreadLocalRandom.current().nextInt()
    val randomLong = ThreadLocalRandom.current().nextLong()
    assertTrue { randomDouble >= 0 }
    assertTrue { randomDouble < 1 }
    assertTrue { randomInteger >= Integer.MIN_VALUE }
    assertTrue { randomInteger < Integer.MAX_VALUE }
    assertTrue { randomLong >= Long.MIN_VALUE }
    assertTrue { randomLong < Long.MAX_VALUE }
}

4. Kotlin.jsを使用した乱数

ランダムなdoubleusing the Math class from the kotlin.js libraryを生成することもできます。

@Test
fun whenRandomNumberWithKotlinJSMath_thenResultIsBetween0And1() {
    val randomDouble = Math.random()
    assertTrue { randomDouble >=0 }
    assertTrue { randomDouble < 1 }
}

5. 純粋なKotlinを使用した任意の範囲の乱数

純粋なKotlinを使用して、そのリストからcreate a list of numbers, shuffle it and then take the first elementを実行できます。

@Test
fun whenRandomNumberWithKotlinNumberRange_thenResultInGivenRange() {
    val randomInteger = (1..12).shuffled().first()
    assertTrue { randomInteger >= 1 }
    assertTrue { randomInteger <= 12 }
}

6. ThreadLocalRandomを使用して指定された範囲の乱数

セクション3に示されているThreadLocalRandomを使用して、特定の範囲の乱数を生成することもできます。

@Test
fun whenRandomNumberWithJavaThreadLocalRandom_thenResultsInGivenRanges() {
    val randomDouble = ThreadLocalRandom.current().nextDouble(1.0, 10.0)
    val randomInteger = ThreadLocalRandom.current().nextInt(1, 10)
    val randomLong = ThreadLocalRandom.current().nextLong(1, 10)
    assertTrue { randomDouble >= 1 }
    assertTrue { randomDouble < 10 }
    assertTrue { randomInteger >= 1 }
    assertTrue { randomInteger < 10 }
    assertTrue { randomLong >= 1 }
    assertTrue { randomLong < 10 }
}

7. 擬似乱数ジェネレーターと安全な乱数ジェネレーター

java.util.Randomの標準JDK実装は、Linear Congruential Generatorを使用して乱数を提供します。 このアルゴリズムの問​​題は、暗号的に強力ではなく、攻撃者がその出力を予測する可能性があることです。

この問題を克服するには、適切なセキュリティが必要な場所にwe should use java.security.SecureRandomを配置します。

fun whenRandomNumberWithJavaSecureRandom_thenResultsInGivenRanges() {
    val secureRandom = SecureRandom()
    secureRandom.nextInt(100)
    assertTrue { randomLong >= 0 }
    assertTrue { randomLong < 100 }
}

SecureRandomは、暗号的に強力な疑似乱数ジェネレーター(CSPRNG)を使用して、暗号的に強力な乱数値を生成します。

アプリケーションは、セキュリティに関連する場所で安全な乱数を生成する他の方法を使用するべきではありません。

8. 結論

この記事では、Kotlinで乱数を生成するいくつかの方法を学びました。

いつものように、このチュートリアルで提示されるすべてのコードはover on GitHubで見つけることができます。