对java中random的思考
2015-06-15 17:03
405 查看
今天又一次去看jdk 7的api的random的时候,对random怎么实现的伪随机数很好奇,在百度中搜索了一下,然后得到了一些启示。
JDK 中有两个随机数类:
一个是 PRNG,也就伪随机数类 java.util.Random,是采用线性同余算法产生的。
另一个是 RNG,也就是 java.util.Random 的子类强随机数 java.security.SecureRandom,这是一个 SPI 类,也就是说具体的算法由 Provider 提供。Sun 给其提供了一个默认的算法——SHA1PRNG。
由于 Random 是采用时间作为随机数种子,如果 hacker 知道随机数产生的时间,那就能重现随机数。而 SecureRandom 属于强随机数,一般不单独采用时间作为随机数种子,还会采用临时文件夹中大小,某个线程从休眠到被唤醒所耗的时间等等一系列无法重现的值作为随机数种子。
SecureRandom 一般用于安全、加密 API,以及 UUID 的生成。
但是什么是线性同余算法以及random怎么实现的random呢?
线性同余方法(LCG)是个产生伪随机数的方法。
它是根据递归公式:
也可以不加B。
其中
是产生器设定的常数。
LCG的周期最大为
,但大部分情况都会少于M。要令LCG达到最大周期,应符合以下条件:
互质;
的所有质因子的积能整除
;
若
是4的倍数,
也是;
都比
小;
是正整数。
线性同余算法有m 、a 、c 和X0 4个参数,通过置Xn + 1 ≡aXn + c (mod m) ,求得随机数序列< Xn > , 这个序列称作线性同余序列。m、a 、c 和X0 分别称做模数、乘数、增量和初始值。线性同余方法速度快,如果对乘数和模数进行适当的选择,可以满足用于评价一个随机数产生器的3 种准则:
1.这个函数应该是一个完整周期的产生函数。也就是说,这个函数应该在重复之前产生出0 到m之间的所有数;
2.产生的序列应该看起来是随机的;
3.这个函数应该用32bit 算术高效实现。
例如在我的算法中,a=7^5;c=0;m=2^31-1; x0为系统时间,但是系统时间,不是很安全,可以增加其他的变量来使这个值更加安全。
JDK 中有两个随机数类:
一个是 PRNG,也就伪随机数类 java.util.Random,是采用线性同余算法产生的。
另一个是 RNG,也就是 java.util.Random 的子类强随机数 java.security.SecureRandom,这是一个 SPI 类,也就是说具体的算法由 Provider 提供。Sun 给其提供了一个默认的算法——SHA1PRNG。
由于 Random 是采用时间作为随机数种子,如果 hacker 知道随机数产生的时间,那就能重现随机数。而 SecureRandom 属于强随机数,一般不单独采用时间作为随机数种子,还会采用临时文件夹中大小,某个线程从休眠到被唤醒所耗的时间等等一系列无法重现的值作为随机数种子。
SecureRandom 一般用于安全、加密 API,以及 UUID 的生成。
但是什么是线性同余算法以及random怎么实现的random呢?
线性同余方法(LCG)是个产生伪随机数的方法。
它是根据递归公式:
也可以不加B。
其中
是产生器设定的常数。
LCG的周期最大为
,但大部分情况都会少于M。要令LCG达到最大周期,应符合以下条件:
互质;
的所有质因子的积能整除
;
若
是4的倍数,
也是;
都比
小;
是正整数。
线性同余算法有m 、a 、c 和X0 4个参数,通过置Xn + 1 ≡aXn + c (mod m) ,求得随机数序列< Xn > , 这个序列称作线性同余序列。m、a 、c 和X0 分别称做模数、乘数、增量和初始值。线性同余方法速度快,如果对乘数和模数进行适当的选择,可以满足用于评价一个随机数产生器的3 种准则:
1.这个函数应该是一个完整周期的产生函数。也就是说,这个函数应该在重复之前产生出0 到m之间的所有数;
2.产生的序列应该看起来是随机的;
3.这个函数应该用32bit 算术高效实现。
例如在我的算法中,a=7^5;c=0;m=2^31-1; x0为系统时间,但是系统时间,不是很安全,可以增加其他的变量来使这个值更加安全。
相关文章推荐
- Spring 系列: Spring 框架简介
- java.sql.SQLException: Connection is closed
- java 记录一下socket的server与clien
- java 时间处理
- java 反射访问成员属性
- Java for LeetCode 220 Contains Duplicate III
- 网页动物园2.0发布,经过几个月的努力,采用JAVA编写!
- LeetCode_32---Longest Valid Parentheses
- eclipse中格式化代码快捷键Ctrl+Shift+F失效
- java中static作用详解
- eclipse的build path
- JAVA基础(一)
- eclipse上的java编程助手软件的使用与配置
- java 后台开发流程
- Java通配符<?>
- java io
- java将阿拉伯数字转化为罗马数字 I II III IV V VI
- Java弱智错误
- 解析Java中的String对象的数据类型
- Java根据sessionId获取Session对象