2014-12-07 63 views
2

基准测试的目的,我想有一个SecureRandom产生确定性输出。这可能是通过使用种子(或者可能是算法的规范)吗?从SecureRandom获取确定性的值?

import java.security.SecureRandom; 
class TestSecureRandom { 
    public static void main(String [] args) { 
     SecureRandom rnd = new SecureRandom(); 
     rnd.setSeed(1); 
     System.out.println(rnd.nextInt()); 
    } 
} 

对我来说,即使指定了种子,上面的程序也会产生不同的值。

+1

根据它的Javadoc(https://docs.oracle.com/javase/7 /docs/api/java/security/SecureRandom.html)它是非确定性的。 'setSeed'只改变它的内部状态,但它仍然是非确定性的。 – 2014-12-07 09:34:36

+0

它是否必须是'SecureRandom'?它可以是一些其他类型的“随机”(例如,“随机”本身)? – 2014-12-07 09:40:08

+0

编号为“接口”。在代码中使用“随机”。 – 2014-12-07 09:49:18

回答

5

这样做的最简单方法可能是让大部分代码仅依赖于Random,并且实例被注入(例如通过将其传递给构造函数)。这样,出于测试目的,您可以通过一个简单的Random传递一个固定的种子 - 但对于实际的需要安全性的运行,您可以传入一个SecureRandom的实例。

1

一切都在documentation清楚地解释:

许多SecureRandom实现是一个伪随机 数发生器(PRNG)的形式,这意味着它们将使用确定 算法,以产生伪随机来自真随机种子的序列。其他实现可以产生真随机数,而其他实现可以使用两种技术的组合。

如果您询问实施,在Linux中它使用/dev/urandom,所以结果是不可预测的。但是,您可以强制SecureRandom使用另一种算法:

SecureRandom rnd = SecureRandom.getInstance("SHA1PRNG"); 

但很多情况下,最合理的想法是使用一些OOP的模式(例如,jon-skeet's answer)。

2

为了覆盖默认的种子,通过PRNG算法名这样

import java.io.UnsupportedEncodingException; 
import java.security.NoSuchAlgorithmException; 
import java.security.SecureRandom; 
class TestSecureRandom { 
    public static void main(String [] args) throws NoSuchAlgorithmException, UnsupportedEncodingException { 
     SecureRandom rnd = SecureRandom.getInstance("SHA1PRNG"); 
     rnd.setSeed("foo".getBytes("us-ascii")); 
     System.out.println(rnd.nextInt()); 
     System.out.println(rnd.nextInt()); 
    } 
} 

输出继电器

-207444710 
-1693504542 
+0

我结束了使用'随机'界面,但这也是有用的知道。 – jaynp 2014-12-22 11:06:49