Java 生成大量随机数的有效方法
我有一个java方法,它必须在很短的时间内生成大量随机数。 我的第一个方法是使用Math.random(它运行得非常快),但我有一个假设,因为我在另一个后面调用Java 生成大量随机数的有效方法,java,random,secure-random,Java,Random,Secure Random,我有一个java方法,它必须在很短的时间内生成大量随机数。 我的第一个方法是使用Math.random(它运行得非常快),但我有一个假设,因为我在另一个后面调用Math.random,所以“random”并不是真正的随机(或更少的随机)的(但我需要它尽可能地随机) 我现在有两个问题: 我的假设是对的,因为在很短的时间内调用的数量,随机输出的随机性变小了吗? 如果答案是1。是的: 以较少的随机性消除问题的最快方法(每次呼叫)是什么 我已经使用过SecureRandom,但它比普通的Math.ran
Math.random
,所以“random”并不是真正的随机(或更少的随机)的(但我需要它尽可能地随机)
我现在有两个问题:
SecureRandom
,但它比普通的Math.random慢至少15倍,这对我的要求来说太慢了。TL;医生:你的假设是错误的。
Math.random
作用于java.util.random
上的单个实例:
返回一个带正号的双精度值,大于或等于
0.0且小于1.0。返回值是从该范围内以(近似)均匀分布伪随机选择的
当这个方法
首先调用,它创建一个新的伪随机数
生成器,与表达式完全相同
new java.util.Random()
从
现在,使用一个带有数字种子的,该数字“很可能不同于此构造函数的任何其他调用。”1
由于这是一个伪随机过程-即,它将从同一种子中给出完全相同的值-从数学中提取数字的速度。随机
对其随机性没有影响。TL;医生:你的假设是错误的。
Math.random
作用于java.util.random
上的单个实例:
返回一个带正号的双精度值,大于或等于
0.0且小于1.0。返回值是从该范围内以(近似)均匀分布伪随机选择的
当这个方法
首先调用,它创建一个新的伪随机数
生成器,与表达式完全相同
new java.util.Random()
从
现在,使用一个带有数字种子的,该数字“很可能不同于此构造函数的任何其他调用。”1
由于这是一个伪随机过程-即,它将从同一种子中给出完全相同的值-您从
数学中提取数字的速度。随机对其随机性没有影响。使用随机类的随机数使用一种算法,该算法会对一个整数进行位损,从而得到一个新的整数。它将使用相同的算法不管你叫它多快或多少次。进步就是进步
要测试这一点,请使用一个数字,如42。然后观察进展。再次用相同的数字播种。相同的精确级数
这种方法的缺点是,这些数字并不是真正随机的。它们是非常随机的,对大多数事情来说都足够好,但不是完全随机的
我通过一系列测试运行了随机方法的输出。它以优异的成绩通过了他们中的大多数,一个是边缘的,一个是平坦的失败。这就是我们所说的那种随机性
此外,由于它使用日期-时间戳来为自己播种,因此在某些情况下它是可以预测的。想象一下,有人在每周一早上启动并运行您的任务,这是该周的第一件事。有一些可预测性,因为它将在周一早上8点到8:30之间运行
所以,对于大多数与安全无关的操作来说,Random已经足够了。甚至有很多
另一方面,SecureRandom将生成真正的随机数。它通过查看系统计时和其他基于无数因素每秒变化的事情来实现这一点
缺点是这些因素在一秒钟内变化非常频繁,因此SecureRandom只能在一段时间内生成有限数量的随机数。它确实试图提前生成一些,并缓存它们以供使用,但您可以破坏缓存
这样,它就像我的反渗透水过滤器。它装有一加仑已经过滤过的水。如果你一次使用一加仑的水,那么你得到的水的过滤速度——大约是每5秒1盎司或者类似的速度。第一加仑是快的,然后它真的很慢。使用随机类的随机数使用一种算法,该算法会对一个int进行一点修改,以得到一个新的int。无论调用它的速度有多快或次数有多少,它都将使用相同的算法。进步就是进步
要测试这一点,请使用一个数字,如42。然后观察进展。再次用相同的数字播种。相同的精确级数
这种方法的缺点是,这些数字并不是真正随机的。它们是非常随机的,对大多数事情来说都足够好,但不是完全随机的
我通过一系列测试运行了随机方法的输出。它以优异的成绩通过了他们中的大多数,一个是边缘的,一个是平坦的失败。这就是我们所说的那种随机性
此外,由于它使用日期-时间戳来为自己播种,因此在某些情况下它是可以预测的。想象一下,有人在每周一早上启动并运行您的任务,这是该周的第一件事。有一些可预测性,因为它将在周一早上8点到8:30之间运行
所以,对于大多数与安全无关的操作来说,Random已经足够了。甚至有很多
另一方面,SecureRandom将生成真正的随机数。它通过查看系统计时和其他基于无数f的每秒变化的事情来实现这一点
Random rand = new Random();
for ( loop ) {
int dice = rand.nextInt(6) + 1;
long l = rand.nextLong();
kiss.util.AESPRNG prng = new kiss.util.AESPRNG();
double [] x = new double [1_000_000];
prng.nextDoubles(x,0,x.length);