Random不够随机的问题
经常使用的 java.util.Random 类,是PRNG,采用线性同余算法产生的,也称为伪随机分布。会发生不够随机的情况,比如以下例子:
public static void main(String[] args) { for (int i = 0; i < 4096; i++) { int r = new Random(i).nextInt(2); System.out.println(r); } }
其输出结果全部都是1
java.util.Random 的子类强随机数 java.security.SecureRandom,是 RNG,是一个 SPI 类,也就是说具体的算法由 Provider 提供。Sun 给其提供了的默认算法(SHA1PRNG)。
由于 Random 是采用时间作为随机数种子,如果 hacker 知道随机数产生的时间,那就能重现随机数。而 SecureRandom 属于强随机数,一般不单独采用时间作为随机数种子,还会采用临时文件夹中大小,某个线程从休眠到被唤醒所耗的时间等等一系列无法重现的值作为随机数种子。
Math.random()方法其实调用的是random的nextDouble()方法。
结论: 使用强随机SecureRandom更安全。