我与commons-lang3系列——RandomUtils

编程过程中经常会有产生随机数的需求,java.util.Random是我经常使用的,举例如下:

// 固定seed
Random t = new Random(100);
for (int i = 0; i < 5; i++) {
    System.out.println(t.nextInt(100) +" ");
}
// 以系统时钟作为seed
Random timeRandom = new Random();
for (int i = 0; i < 5; i++) {
    System.out.println(timeRandom.nextInt(100) +" ");
}

伪随机数和真随机数

先了解一下这2个概念:

  • 真随机数,通过物理实验得出,比如掷钱币、骰子、转轮、使用电子元件的噪音、核裂变等
  • 伪随机数,通过一定算法和种子得出。软件实现的是伪随机数

而伪随机数也分为强伪随机数和弱伪随机数两类:

  • 强伪随机数,难以预测的随机数,例如java.security.SecureRandom
  • 弱伪随机数,易于预测的随机数,例如java.util.Random

也就是说我们程序里用的都是伪随机数,而弱伪随机数(比如基于固定seed或者系统时钟seed)是可预测(重复)的,参考如下代码,seed固定为100的Random实例,产生的随机数序列是一模一样的,也就是说如果一旦黑客知道了你的seed,完全可以预测程序的下一个随机数是什么。

//固定seed
Random t = new Random(100);
for (int i = 0; i < 5; i++) {
    System.out.println(t.nextInt(100) +" ");
}
Random t2 = new Random(100);
for (int i = 0; i < 5; i++) {
    System.out.println(t2.nextInt(100) +" ");
}

这个会有什么危害呢?如果随机数影响了程序的校验逻辑,比如用于产生随机的短信的验证码,如果被不法分子获取了seed,那就可以破解验证码的校验流程了,后果非常严重。但是也不是所有的场景都要用强伪随机数,不是安全场景的随机数,使用Random就好,如果想了解详细的细节,请参考文章:http://netsecurity.51cto.com/art/201605/511983.htm

RandomUtils简介

commons-lang3里有RandomUtils工具类,它里面提供里多个函数可以方便的的产生随机数,生成int,long,double,boolean,float,bytes几种类型,能满足基本的随机数产生需求,如下图:

由于是产生随机数的静态工具类,类初始化时内部已经创建了java.util.Random实例,其他的静态工具方法都是基于这个实例产生的随机数,所以其本质上也是伪随机数,而且是弱伪随机数(基于系统时间的seed):

private static final Random RANDOM = new Random();

欢迎关注我的个人的博客www.zhijianliu.cn, 虚心求教,有错误还请指正轻拍,谢谢

版权声明:本文出自志健的原创文章,未经博主允许不得转载

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章