Android 上 Kotlin 的随机数生成:底层原理是什么?

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

如何让 Android “掷骰子”?解析 Kotlin 中的随机数生成

\n\n

你是否曾好奇过,你的手机是如何“选择”一个随机数的?看似简单的任务——获取一个 5 到 10 之间的随机整数。但在 Android 和 Kotlin 的底层,隐藏着一整套机制,它不仅关系到便利性,还关系到你应用的安全性。难怪 “How can I generate random number in specific range in Android?” 这个问题在 Stack Overflow 上获得了数千次浏览。我们不仅会给出现成的答案——我们还会深入源码,弄清楚实际发生了什么。

\n\n

在本文中,你将了解到:

\n
    \n
  • 如何在 Kotlin 中正确生成指定范围内的随机数。
  • \n
  • kotlin.random.Random、java.util.Random 和 SecureRandom 之间的区别。
  • \n
  • 为什么博彩游戏需要一种类,而密码生成需要另一种。
  • \n
  • 如何避免那些将“随机性”变成可预测性的典型错误。
  • \n
\n\n

开始吧!

\n\n

经典方式:Kotlin 中的 Random(以及为什么它并不总是正确的)

\n\n

最显而易见的方法是使用 kotlin.random.Random。它内置于语言中,开箱即用。以下是生成 0 到 100(含)之间随机数的方法:

\n\n
import kotlin.random.Random\n\nfun main() {\n    val randomNumber = Random.nextInt(0, 101) // 从 0 到 100(含)\n    println("随机数: $randomNumber")\n}
\n\n

一切都很简单。但让我们看看底层。在 JVM 平台上,Random.nextInt(from, until) 内部使用了 java.util.Random。而后者又通过 线性同余生成器 (LCG) 生成数字。公式很简单:

\n\n

new_seed = (old_seed * A + C) mod M

\n\n

其中 A、C 和 M 是常量。这很快,但 不具备密码学安全性。如果攻击者知道了几个数字,他们就可以恢复种子并预测所有后续数字。

\n\n

何时使用: 用于游戏(非赌博)、从列表中随机选择元素、在普通应用中洗牌。

\n\n

进阶用法:用于多线程的 ThreadLocalRandom

\n\n

如果你的应用大量使用协程或多线程,普通的 Random 可能会成为瓶颈。每次调用 nextInt() 都会进行同步,以避免竞态条件。解决方案是使用 Java 中的 ThreadLocalRandom:

\n\n
import java.util.concurrent.ThreadLocalRandom\n\nfun getRandomInRange(min: Int, max: Int): Int {\n    return ThreadLocalRandom.current().nextInt(min, max + 1)\n}
\n\n

这个类为每个线程分配一个单独的 Random 实例。不需要同步——每个线程都使用自己的生成器。在实践中,这可以在多线程场景中提升性能。

\n\n

安全第一:SecureRandom

\n\n

现在想象一下,你正在生成一次性密码 (OTP) 或用于恢复访问的令牌。使用普通的 Random 是一种错误。这时需要用到 SecureRandom:

\n\n
import java.security.SecureRandom\n\nfun generateSecureCode(length: Int): String {\n    val secureRandom = SecureRandom()\n    val digits = "0123456789"\n    return (1..length)\n        .map { digits[secureRandom.nextInt(digits.length)] }\n        .joinToString("")\n}
\n\n

SecureRandom 从操作系统的熵源收集熵:麦克风噪音、按键时间(在模拟器中,来自 /dev/random 或 /dev/urandom 文件)。这使其不可预测。但代价是速度——它可能比普通的 Random 慢几十倍。

\n\n

重要提示: 在 Android 上,S

博客

书籍推荐