1. 序章

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

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

Kotlinでランダムな数値を生成する最も簡単な方法は、java.lang.Mathを使用することです。 以下の例では、0から1までのランダムなdouble数を生成します。

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

3. ThreadLocalRandomを使用した乱数

java.util.concurrent.ThreadLocalRandom を使用して、ランダムなdouble、integer、またはlong値を生成することもできます。 この方法で生成された整数値とlong値は、正または負の両方になります

ThreadLocalRandomはスレッドセーフであり、マルチスレッド環境でより優れたパフォーマンスを提供します。これは、スレッドごとに個別の 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を使用した乱数

kotlin.jsライブラリのMathクラスを使用して、ランダムなdoubleを生成することもできます。

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

5. PureKotlinを使用した特定の範囲のランダム数

純粋なKotlinを使用して、番号のリストを作成し、それをシャッフルして、そのリストから最初の要素tを取得できます。

@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実装は、線形合同法を使用してランダムな数値を提供します。 このアルゴリズムの問題は、暗号的に強力ではなく、攻撃者がその出力を予測する可能性があることです。

この問題を解決するには、適切なセキュリティが必要な場所でjava.security.SecureRandomを使用する必要があります。

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

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

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

8. 結論

この記事では、Kotlinでランダムな数値を生成するいくつかの方法を学びました。

いつものように、このチュートリアルで提示されるすべてのコードは、GitHubにあります。