Java 随机数比较和分析
作者:网络转载 发布时间:[ 2012/8/2 10:36:39 ] 推荐标签:
概况:
本文概述2种jdk的随机数实现方式,旨在了解其运行机理。并得出运行效率比较。但这2种随机数生成还是会存在一定安全风险(伪随机数有可能会被猜出随机序列),后还给出另一种相对更安全的随机数产生方式。附录还给出jdk的nextInt(n)函数的代码分析。
一、2种产生方式:
一般通过jdk获取0~N(N为自然数)的随机数可以通过下面2种方式获取
1、Math.random() ——返回[0,1)的随机小数,通过(int) (n * Math.random())即可获取[0,n)的随机数
2、java.util.Random的nextInt(n)方法 ——返回[0,n)的随机小数
在jdk1.6实现中,Math.random()实现如下:
public static double random() {
if (randomNumberGenerator == null) initRNG(); // randomNumberGenerator是Math中持有的Random类单例
return randomNumberGenerator.nextDouble();
}
randomNumberGenerator 原来Math.random()还是基于Random类实现了随机数生成。
下面再看下Random类的nextDouble()和nextInt(n)分别怎么实现:
public double nextDouble() {
return (((long)(next(26)) << 27) + next(27))
/ (double)(1L << 53);
}
public int nextInt(int n) {
if (n <= 0)
throw new IllegalArgumentException("n must be positive");
if ((n & -n) == n) // i.e., n is a power of 2
return (int)((n * (long)next(31)) >> 31);
int bits, val;
do {
bits = next(31);
val = bits % n;
} while (bits - val + (n-1) < 0); // 这里为什么要这么判断,请见附录a
return val;
}
从2段程序中可以看到,终实现随机数的生成还是依赖于next(n)。
(注:next(n)的功能是产生n位bits,每个bit位随机为0或1,当n<32时,next(n)产生的随机数范围为0~2^31-1,当n=32时,产生随机数范围为-2的31次方~2^31-1。源码中的next函数终返回return (int)(nextseed >>> (48 - bits)) 是因为随机种子是48位,所以终返回的是随机种子的高n位bit)
而nextDouble()中铁定调用了2次next(n),而nextInt(n)则不确定,但平均调用next(n)的次数在2次以下(见附录b证明)。所以nextInt(n)比nextDouble()获取随机数的效率要高。
另外,通过(int) (n * Math.random())获取的整数随机数其实是通过double随机数近似而来,准确性相对nextInt(n)来说应该会低些。
二、下面是运行速度比较:
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11