当前位置: 代码迷 >> Java相关 >> Math.Random()随机数是怎么产生的
  详细解决方案

Math.Random()随机数是怎么产生的

热度:8221   发布时间:2013-02-25 21:46:20
Math.Random()随机数是如何产生的?
如题

------解决方案--------------------------------------------------------
JDK 中有两个随机数类。

一个是 PRNG,也就伪随机数类 java.util.Random,是采用线性同余算法产生的。

另一个是 RNG,也就是 java.util.Random 的子类强随机数 java.security.SecureRandom,这是一个 SPI 类,也就是说具体的算法由 Provider 提供。Sun 给其提供了一个默认的算法——SHA1PRNG。

由于 Random 是采用时间作为随机数种子,如果 hacker 知道随机数产生的时间,那就能重现随机数。而 SecureRandom 属于强随机数,一般不单独采用时间作为随机数种子,还会采用临时文件夹中大小,某个线程从休眠到被唤醒所耗的时间等等一系列无法重现的值作为随机数种子。

SecureRandom 一般用于安全、加密 API,以及 UUID 的生成。

------解决方案--------------------------------------------------------
PS:所谓的 SPI 类指的是 service provider interface,即服务提供商接口。是一种软件的扩展机制,在 Java 中表现为某些实现由 service provider 实现,而使用者只需要使用不同的参数调用相同的 API 就能使用其他 provider 提供的服务。

Java 中的 SPI 类,一般为这种形式:XxxxxSpi,表示 Xxxxx 是一个 SPI 类,也就是说允许其他 provider 通过继承 XxxxxSpi 类来扩展 Xxxxx 的服务实现。而对于开发人员来说,不需要关心 XxxxxSpi 类,仅仅需要关心 Xxxxx 类就可以了。

SPI 类充斥着 Java 中的各各方面,比如在 J2SE 中关于安全、加密的 API 全部都是 SPI 类,在 J2EE 中的 SPI 就更多了。

加载 SPI 实现一般有两种方法:

在 J2SE 中采取继承 SPI 类,使用特定的 API 注册 SPI 实现,以达到类库索的目的。

在 J2EE 中采用在 provider 在其 jar 包的 META-INF/services 中写上具体的 SPI 工厂,SPI 工厂需要实现 SPI 的某个工厂接口。比如 JPA 的实现中需要在 provider 提供的实现 jar 包的 META-INF/services 含 有一个文件名 javax.persistence.spi.PersistenceProvider 的文件,文件内容为实现这个文件名所表示接口口的实现。
  相关解决方案