什么是Java伪随机数,基础打牢。 #程序员 #Java #编程

你一定听说过这样一个词,伪随机数,你有没有这样的疑惑,为什么不用真随机,要用的个假的?

先说一个结论:

Java Random英/ˈrændəm/ 随机数生成不安全,如果同时泄漏第一个和第二个随机数,那么后面的随机数序列可以被破解。

Java Random类 使用 线性同余生成器算法(Linear Congruential Generator)来生成伪随机数。所谓伪随机数是指,如果我们使用相同的种子(seed)来生成随机数序列,那么得到的结果将是一样的。

java 复制代码
    Random random = new Random();
    int i = random.nextInt(10);
    System.out.println(i);

例如

java 复制代码
    Random random = new Random(0);
    int cnt = 10;
    for (int i = 0; i < cnt; i++) {
        System.out.println(random.nextLong());
    }

这意味着,当我们设置种子为 0 时,每次运行代码得到的随机数序列将是相同的。无论是在任何时间,还是在任何设备上,以下代码生成的随机数始终保持一致。这也意味着一旦黑客获得了你的种子"seed",他们可以预测出你所生成的所有随机数。

要想生成不同的随机数序列,我们需要使用不同的种子。

...

庆幸的事,Java Random 并没有使用 0 作为缺省值,而是使用了更为复杂的方式,使用动态随机值作为默认种子。

那初始化种子如何生成呢?

java 复制代码
private static final AtomicLong seedUniquifier = new AtomicLong(8682522807148012L);
private static long seedUniquifier() {
    // L'Ecuyer, "Tables of Linear Congruential Generators of
    // Different Sizes and Good Lattice Structure", 1999
    for (;;) {
        long current = seedUniquifier.get();
        long next = current * 181783497276652981L;
        if (seedUniquifier.compareAndSet(current, next))
            return next;
    }
}

这段代码使用AtomicLong 计算种子,很明显是为了保证多线程场景下创建多个Random对象时,产生不同的种子值。在seedUniquifier方法中,使用了AtomicLong.compareAndSet方法来保证每次执行该方法时生成不同的初始种子值。通过这种方法,我们可以确保在多线程应用中,当出现种子冲突时,我们可以通过CAS操作(Compare and Swap)进行重试,以确保每个线程创建的Random对象的初始种子值是不同的。

在代码中,通过将不同的初始种子值与当前系统时间的纳秒进行异或运算,可以保证每次Random执行都会得到不同的种子。

到这里大家对 Java Random 一定有所了解了吧。在强安全性场景下一定要重视起来。

相关推荐
yaoxin5211235 分钟前
397. Java 文件操作基础 - 创建常规文件与临时文件
java·开发语言·python
小短腿的代码世界9 分钟前
Qt日志系统深度解析:从qDebug到企业级日志框架
开发语言·qt
dFObBIMmai14 分钟前
MySQL主从同步中大事务导致的延迟_如何拆分大事务优化同步
jvm·数据库·python
szccyw017 分钟前
mysql如何限制特定存储过程执行权限_MySQL存储过程安全访问
jvm·数据库·python
小白学大数据23 分钟前
Python 自动化爬取网易云音乐歌手歌词实战教程
爬虫·python·okhttp·自动化
REDcker1 小时前
浏览器端Web程序性能分析与优化实战 DevTools指标与工程清单
开发语言·前端·javascript·vue·ecmascript·php·js
风之所往_2 小时前
Python 3.0 新特性全面总结
python
2401_882273722 小时前
如何在 CSS 中正确加载本地 JPG 背景图片
jvm·数据库·python
极客先躯2 小时前
高级java每日一道面试题-2025年11月24日-容器与虚拟化题[Dockerj]-runc 的作用是什么?
java·oci 的命令行工具·最小可用·无守护进程·完全标准·创建容器的核心流程·runc 核心职责思维导图
用户60648767188962 小时前
AI 抢不走的技能:用 Claude API 构建自动化工作流实战
java