Java实现真假随机数详解

 更新时间:2024年11月13日 10:26:55   作者:逸风尊者  
伪随机数和真随机数是计算机科学和统计学中非常重要的概念,理解它们之间的差异有助于选择合适的随机数生成方案,本文将使用Java实现真假随机数,感兴趣的可以了解下

伪随机数

定义:伪随机数(Pseudorandom Number)是通过算法生成的数,其看似随机,但实际上是确定性的。

生成方式:通常使用数学公式或算法,如线性同余法,基于一个初始值(种子)产生一个序列。

特点

  • 可再现性:给定相同的种子,伪随机数生成器总是会产生相同的数字序列。这对于测试和调试非常有用。
  • 效率高:生成速度快,适用于需要大量随机数的场景。
  • 周期性:序列是有限长的,最终会重复。

应用场景:适用于模拟、数值分析、游戏开发等不要求绝对随机性的领域。

真随机数

定义:真随机数(True Random Number)依赖于不可预测的物理现象,如放射性衰变、热噪声等。

生成方式:通常通过硬件设备采集自然界中不可预测的事件。

特点

  • 不可再现性:相同条件下无法生成相同的数列。
  • 不可预测性:没有可预测的模式,真正随机。
  • 复杂度高:生成过程可能较慢,且需要专门的硬件支持。

应用场景:用于安全性要求极高的领域,如密码学、加密密钥生成等。

java伪随机数

java中的Random类是用于生成伪随机数的工具。其底层实现依赖于一个称为**线性同余生成器(Linear Congruential Generator, LCG)**的算法,这是一种常用的伪随机数生成算法。

线性同余生成器 (LCG)

LCG 是一种通过以下公式生成随机序列的算法:

[ X_{n+1} = (a \times X_n + c) \mod m ]

其中:

( X ) 是随机数序列。

( a ), ( c ), 和 ( m ) 是常量:

  • ( m ) 是模量,通常是大的质数或2的幂。
  • ( a ) 是乘数。
  • ( c ) 是增量。

( X_0 ) 是初始种子值。

Java Random 类的实现

在Java中,java.util.Random类使用64位的LGC算法,其中:

  • 模量 ( m = 2^{48} )
  • 常量 ( a = 25214903917 )
  • 增量 ( c = 11 )

每次生成一个新的随机数时,Random类会更新当前种子以生成下一个数。

种子(Seed)

  • 初始化:如果不指定种子,Random会使用系统时间作为默认种子。
  • 再现性:相同的种子会产生相同的随机数序列,这对测试和调试非常有用。

内部方法

Java Random类的核心方法是next(int bits),用于生成给定数量的随机bit。其他如nextInt(), nextDouble()等方法都基于next(bits)来实现,只是通过不同的方式组合这些bit。

protected int next(int bits) {
    long oldseed, nextseed;
    AtomicLong seed = this.seed;
    do {
        oldseed = seed.get();
        nextseed = (oldseed * 25214903917L + 11) & ((1L << 48) - 1);
    } while (!seed.compareAndSet(oldseed, nextseed));
    return (int)(nextseed >>> (48 - bits));
}

代码解释

1.变量声明

  • oldseed: 当前种子值。
  • nextseed: 用于计算下一个种子值。
  • seed: 一个AtomicLong类型,用于保证线程安全地更新种子。

2.获取当前种子值

oldseed = seed.get();: 从原子变量seed中读取当前的种子值。

3.计算下一个种子值

nextseed = (oldseed * multiplier + addend) & mask;

使用线性同余生成器(LCG)公式来计算新的种子值。

multiplieraddendmask是常量,其中:

  • multiplier是乘数。
  • addend是增量。
  • mask用于确保结果在有效范围内(通常是m-1,其中m是模量)。

4.更新种子值

while (!seed.compareAndSet(oldseed, nextseed));

  • 使用compareAndSet方法尝试将oldseed更新为nextseed
  • 如果在此期间其他线程修改了seed,则compareAndSet会返回false,循环继续,直到成功为止。这种机制确保了多线程环境下的原子性更新。

5.生成随机数

return (int)(nextseed >>> (48 - bits));

  • 将新的种子值右移以获取所需的随机位数。
  • >>>操作符确保左侧用零填充,无符号右移。
  • (48 - bits)确定要保留多少位的随机数。

总结

这个方法利用种子值和线性同余生成器算法来生成伪随机数,并通过AtomicLong保证了多线程情况下的线程安全。它返回的是指定位数的整数形式的随机数,将会被其他方法如nextInt()nextDouble()进一步处理,以提供给用户所需的随机数类型。

java真随机数

在Java中,实现真随机数通常需要依赖外部硬件设备或者操作系统的功能,因为纯软件方法生成的都是伪随机数。

使用java.security.SecureRandom

虽然SecureRandom类本质上仍然是伪随机的,但它可以配置为使用底层操作系统提供的熵源,这样生成的随机数接近于真随机数,特别是在安全性要求较高的应用场景中。

import java.security.SecureRandom;

public class TrueRandomExample {
    public static void main(String[] args) {
        SecureRandom secureRandom = new SecureRandom();
        
        // 生成一个随机整数
        int randomInt = secureRandom.nextInt();
        System.out.println("Random Integer: " + randomInt);
        
        // 生成一个0到100之间的随机整数
        int boundedInt = secureRandom.nextInt(101);
        System.out.println("Bounded Random Integer (0-100): " + boundedInt);

        // 生成随机字节数组
        byte[] randomBytes = new byte[16];
        secureRandom.nextBytes(randomBytes);
        System.out.println("Random Bytes: " + java.util.Arrays.toString(randomBytes));
    }
}

SecureRandom 的特点

  • 更多的熵来源SecureRandom可以利用操作系统的熵池(如Linux的/dev/random/dev/urandom),这些熵源采集的是物理世界中的不确定性。
  • 适用于安全应用:广泛用于加密、令牌生成等需要高质量随机数的场合。
  • 可配置性:允许指定算法和提供者,以满足不同的安全需求。

真随机数的硬件支持

如果需要真正的随机数,可以使用硬件随机数生成器(HRNG),通常通过专用的硬件设备来实现,如:

  • Intel的RDRAND指令集:在支持的处理器上,这些指令可以直接提供硬件级别的随机数。
  • 其他硬件设备:市面上有专门的USB接口的随机数生成器,它们通过例如热噪声等物理现象生成随机数。

在Java中,直接调用这些硬件设备需要通过JNI(Java Native Interface)或者底层的操作系统API,这涉及到特定平台的调用和配置。对于大多数应用来说,SecureRandom已经能够提供足够好的随机数质量。

扩展:热噪声随机数如何理解

热噪声随机数是基于物理现象生成的随机数,其主要原理是利用电子设备中的热噪声。热噪声,又称为约翰逊-奈奎斯特噪声,是由于导体中自由电子的热运动引起的电压和电流波动。这种波动在微观上是不可预测的,因此可以用作随机数的来源。

理解热噪声随机数的关键点

物理基础

  • 热噪声是由导体内电子的随机热运动产生的,与温度有关。
  • 这种噪声存在于所有有电阻的导体中,并且无法完全消除。

生成过程

  • 将热噪声信号通过放大器进行放大,以便测量。
  • 使用模数转换器(ADC)将模拟信号转换为数字信号,从而得到随机二进制数。

优点

  • 真正的随机性:因为热噪声是由量子力学效应导致的,理论上是不可预测的,这使得它非常适合用于安全相关应用,如加密密钥生成。
  • 不重复性:每个样本都是独立的,不依赖于之前的任意值或状态。

应用场景

用于硬件随机数生成器(HRNG),这些设备广泛应用于需要高安全性和高质量随机数的领域,如密码学、安全通信等。

实现难点

  • 需要专门的硬件支持,比如随机数生成芯片或设备。
  • 噪声的放大和测量需要精确的电路设计,以确保环境噪声不会干扰结果。

通过理解热噪声及其应用,我们可以更好地选择适合各种需求的随机数生成器。对于一般的软件应用,伪随机数生成已经足够,而在高度安全的场合,硬件级别的真随机数生成是必需的。

到此这篇关于Java实现真假随机数详解的文章就介绍到这了,更多相关Java真假随机数内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java中利用BitMap位图实现海量级数据去重

    Java中利用BitMap位图实现海量级数据去重

    有许多方法可以用来去重,比如使用列表、集合等等,但这些方法通常只适用于一般情况,然而,当涉及到大量数据去重时,常见的 Java Set、List,甚至是 Java 8 的新特性 Stream 流等方式就显得不太合适了,本文给大家介绍了Java中利用BitMap位图实现海量级数据去重
    2024-04-04
  • 关于springmvc-servlet中的配置小知识详解

    关于springmvc-servlet中的配置小知识详解

    这篇文章主要介绍了关于springmvc-servlet中的配置小知识详解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12
  • java中Object类4种方法详细介绍

    java中Object类4种方法详细介绍

    大家好,本篇文章主要讲的是java中Object类4种方法详细介绍,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2022-01-01
  • Java深度优先遍历解决排列组合问题详解

    Java深度优先遍历解决排列组合问题详解

    这篇文章主要介绍了Java深度优先遍历解决排列组合问题详解,深度优先搜索是递归过程,带有回退操作,因此需要使用栈存储访问的路径信息,当访问到的当前顶点没有可以前进的邻接顶点时,需要进行出栈操作,将当前位置回退至出栈元素位置,需要的朋友可以参考下
    2024-01-01
  • IDEA连接mysql数据库报错的解决方法

    IDEA连接mysql数据库报错的解决方法

    这篇文章主要介绍了IDEA连接mysql数据库报错的解决方法,文中有非常详细的图文示例,对出现Server returns invalid timezone. Go to ‘Advanced‘ tab and set ‘serverTimezone‘ prope报错的小伙伴们很有帮助哟,需要的朋友可以参考下
    2021-05-05
  • Java工程中可执行JAR两种打包方式详解

    Java工程中可执行JAR两种打包方式详解

    这篇文章主要为大家详细介绍了Java工程中可执行JAR两种打包方式,一体化可执行包和带外部依赖lib的可执行包,有需要的小伙伴可以学习一下
    2024-04-04
  • JAVA POI设置EXCEL单元格格式用法举例

    JAVA POI设置EXCEL单元格格式用法举例

    这篇文章主要给大家介绍了关于JAVA POI设置EXCEL单元格格式用法的相关资料,POI中可能会用到一些需要设置EXCEL单元格格式的操作,需要的朋友可以参考下
    2023-08-08
  • ibatis结合oracle批量插入三种方法的测评

    ibatis结合oracle批量插入三种方法的测评

    今天小编就为大家分享一篇关于ibatis结合oracle批量插入三种方法的测评,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12
  • 一文详细讲解Java的父子继承、方法的重写与super关键字

    一文详细讲解Java的父子继承、方法的重写与super关键字

    Java中继承是通过extends关键字实现,帮助减少代码重复,提高复用性,子类继承父类的属性和方法,但私有成员除外,方法重写(override)使子类改造父类方法以适应新功能,这篇文章主要介绍了Java的父子继承、方法的重写与super关键字的相关资料,需要的朋友可以参考下
    2024-10-10
  • springboot实现返回视图而不是string的方法

    springboot实现返回视图而不是string的方法

    这篇文章主要介绍了springboot实现返回视图而不是string的方法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01

最新评论