我正在尝试按照下面的方式调整一个整数数组,
和http://en.wikipedia.org/wiki/Fisher-Yates_shuffle,
“当Fisher-Yates shuffle与伪随机数发生器或PRNG一起使用时会出现另一个问题:因为这样的发生器输出的数字序列完全取决于序列开始时的内部状态,shuffle由这样的发电机驱动不可能产生比发电机具有不同可能状态更明显的排列。......“
填充种子字节数组的最简单方法是什么? 即。
byte [] seed = new byte [2048]; //用随机的东西填充种子字节,最简单的方法是什么? SecureRandom secureRandom =新的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;
}
答案 0 :(得分:3)
这是一篇好文章:“A Java Programmer’s Guide to Random Numbers”
基本上,a)你不想使用java.util.Random
,因为它表现出周期性行为(糟糕的随机性),b)SecureRandom
比java.util.Random
有很大改进,但取决于对于要混洗的元素数量,它提供的自由度可能太小(有关详细信息,请参阅this section)。另一个问题是SecureRandom
非常慢。如果您遇到性能问题,可以按照上面的链接查看速度超过SecureRandom
的其他PRNG。
答案 1 :(得分:0)
我认为数组的大小并不像其内容那么重要。 一种常见的做法是在当前时间创建种子。 您也可以要求用户(如果可能)应用一些随机键盘或鼠标输入。我在密码管理器中注意到了这种技术。
一切都取决于您的需求。我敢打赌,采用System.currentTimeMillis()是非常明智的方法(可选择你可以多次连接或者哈希来玩它)。