2012-01-02 63 views
1

我试图洗牌整数按照下面的阵列,爪哇SecureRandom的内部状态

和从http://en.wikipedia.org/wiki/Fisher-Yates_shuffle

当费 - 耶茨洗牌与伪随机数使用的“出现的另一个问题发生器或PRNG:由于这种发生器输出的数字序列完全由其序列开始时的内部状态决定,因此由这样的发生器驱动的混洗不可能产生比发生器具有明显可能状态更多不同的排列。 ..“

  1. 如果我的SecureRandom生成器拥有大量字节,这足够了吗?
  2. 填充种子字节数组最简单的方法是什么? 即

    字节[]种子=新的字节[2048]; //用随机的东西填充种子字节,最简单的方法是什么? SecureRandom secureRandom = new SecureRandom(seed);

代码:

/** 
* http://en.wikipedia.org/wiki/Fisher-Yates_shuffle 
* 
* To shuffle an array a of n elements (indices 0..n-1): 
*  for i from n − 1 downto 1 do 
*   j ← random integer with 0 ≤ j ≤ i 
*   exchange a[j] and a[i] 
*/ 
public int[] shuffle (int[] inSet) { 

    int [] returnSet = Arrays.copyOf(inSet, inSet.length); 

    for(int i = inSet.length-1; i > 0; i--) { 

     // j ← random integer with 0 ≤ j ≤ i 
     int j = secureRandom.nextInt(i+1); 

     // swap returnSet[i] and returnSet[j] 
     int temp = returnSet[i]; 
     returnSet[i] = returnSet[j]; 
     returnSet[j] = temp; 
    } 
    return returnSet; 
} 
+0

您确定您需要/想要使用* SecureRandom *吗? - 它实际上是用于加密操作。 顺便说一句,我已经看到Android设备上的/ dev/random和/ dev/urandom,这对于PRNG的质量播种来说可能是一个不错的选择。用于密码学。 – JimmyB 2012-01-02 13:05:55

回答

0

我认为,数组的大小并不像它的内容很重要。 一个常见的做法是在当前时间创建种子。 您还可以要求用户(如果可能)应用一些随机键盘或鼠标输入。我在密码管理器中注意到了这种技术。

一切都取决于您的需求。我敢打赌,相当明智的方法是采取System.currentTimeMillis()(可选地,您可以通过多次加入或散列它来玩它)。

+0

数组的内容是不相关的。数组正在被“洗牌”,这意味着正在生成随机排列然后应用。 – 2012-01-02 15:11:55

3

这里是一个很好的文章:“A Java Programmer’s Guide to Random Numbers

基本上,)你不希望使用java.util.Random,因为它是展品周期行为(坏的随机性),B)SecureRandom是一个很大的进步了java.util.Random,但取决于您想要随机播放的元素数量,它提供的自由度可能太小(有关详细信息,请参见this section)。另一个问题是SecureRandom相当慢。如果您遇到性能问题,可以按照上面的链接查找比SecureRandom更快的备用PRNG。