2012-01-02 57 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。