Random和SecureRandom详解

[H B BC] Random object created and used only once [DMI_RANDOM_USED_ONLY_ONCE]

This code creates a java.util.Random object, uses it to generate one random number, and then discards the Random object. This produces mediocre quality random numbers and is inefficient. If possible, rewrite the code so that the Random object is created once and saved, and each time a new random number is required invoke a method on the existing Random object to obtain it.

If it is important that the generated Random numbers not be guessable, you must not create a new Random for each random number; the values are too easily guessable. You should strongly consider using a java.security.SecureRandom instead (and avoid allocating a new SecureRandom for each random number needed).

 

先看看下面这段FindBugs认为有问题的代码:

public   int  getRandom( int  seed) {
    
return   new  Random(seed). nextInt ();
}

看BUG解释,FindBugs建议是:

1.new一个Random的对象,保存之,然后每次都使用这个对象去获取随机数,而不要每次new一个Random对象去获取。

2.FindBugs强烈推荐使用java.security.SecureRandom代替Random。

根据以上要求,我修改了我的代码:

复制代码
public   class  Test   extends  Thread{
    
private  SecureRandom ran;

    Test(
int  seed){
        ran 
=   new  SecureRandom();
    }
    
    
public   int  getRandom( int  seed) {
        
return  ran.nextInt();
    }
}
复制代码

至于为什么FindBugs要这样建议,它这里没有说,我也不太确定,但我的这样猜测的:

1.现在所谓的随机函数Random都是伪随机,不是真正意义上的随机,他们都是使用一个初始值(比如:当前时间),然后把初始值放入随机算法生成随机数。

2.如果每次都new Random()可能会影响随机性,这个可以看看下面代码:

 

复制代码
System.out.println( new  Date().getTime());
System.out.println(
new  Random( new  Date().getTime()).nextInt());
System.out.println(
new  Date().getTime());
System.out.println(
new  Random( new  Date().getTime()).nextInt());
System.out.println(
new  Random( new  Date().getTime()).nextInt());
System.out.println(
new  Random( new  Date().getTime()).nextInt());
System.out.println(
new  Random( new  Date().getTime()).nextInt());
System.out.println(
new  Random( new  Date().getTime()).nextInt());
System.out.println(
new  Random( new  Date().getTime()).nextInt());
System.out.println(
new  Random( new  Date().getTime()).nextInt());
System.out.println(
new  Random( new  Date().getTime()).nextInt());
System.out.println(
new  Random( new  Date().getTime()).nextInt());
复制代码

输出的结果是:

 

复制代码
1235021925734
779046670
1235021925734
779046670
779046670
779046670
779046670
779046670
779046670
779046670
779046670
779046670
复制代码
为什么会这样??其实就是因为在很短的时间内,两次getTime()的值是相等的,而Random有是伪随机的,如果每次都new一个Random然后获取其随机数。从结果可以看出风险了。这样有可能每次获得的随机数值都是相同的。

3.每次都生成对象肯定比每次都使用同一个对象的效率要低。

4.SecureRandom可能是对Random在随机算法上做了改进,使之更安全。(还没看源代码,这个也仅仅是我的猜测而已)

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值