1

我正在尝试按照以下方式对整数数组进行洗牌,

并来自http://en.wikipedia.org/wiki/Fisher-Yates_shuffle

“当 Fisher-Yates shuffle 与伪随机数生成器或 PRNG 一起使用时,会出现另一个问题:由于此类生成器输出的数字序列完全由其在序列开始时的内部状态决定,因此由此类驱动的 shuffle生成器不可能产生比生成器具有不同的可能状态更多的不同排列。......“

  1. 如果我用很多字节为我的 SecureRandom 生成器播种就足够了吗?
  2. 填充种子字节数组的最简单方法是什么?IE

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

代码:

/**
 * 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;
}
4

2 回答 2

3

这是一篇好文章:“随机数的 Java 程序员指南

基本上,a)你不想使用java.util.Random它,因为它表现出周期性行为(坏随机性),b)SecureRandom是一个很大的改进java.util.Random,但根据你想要洗牌的元素数量,它提供的自由度可能是太小(详见本节)。还有一个问题是SecureRandom速度很慢。如果您有性能问题,您可以按照上面的链接获取比SecureRandom.

于 2012-01-02T15:14:26.383 回答
0

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

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

于 2012-01-02T12:57:35.567 回答