2012-01-02 6 views
1

私はフィッシャーイェーツシャッフルは、擬似乱数を使用する場合、追加問題が発生する」、下記のとおり、整数の配列をシャッフルしようとしているのJavaのSecureRandom内部状態

http://en.wikipedia.org/wiki/Fisher-Yates_shuffleから、

よ発電機またはPRNG:そのような発電機によって出力される数列は、シーケンスの開始時にその内部状態によって完全に決定されるので、そのような発電機によって駆動されるシャッフルは、発電機が別個の可能な状態を有するよりも、 .. "

  1. 多くのバイトでSecureRandomジェネレータをシードすると十分ですか?
  2. シードバイト配列を埋める最も簡単な方法は何ですか? すなわち、

    バイト[] seed =新しいバイト[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

* SecureRandom *を使用する必要がありますか? - 実際には暗号操作での使用を意図しています。 Btw、Androidデバイスで/ dev/randomと/ dev/urandomを見たことがあります。これはPRNGの品質シード作成に適しています。暗号のために。 – JimmyB

答えて

0

私は、配列のサイズは、その内容として、それほど重要ではないと思われます。 一般的な方法の1つは、現在の時間にシードを作成することです。 また、ユーザーに(可能であれば)ランダムなキーボードまたはマウス入力を適用するよう依頼することもできます。私はパスワードマネージャーにこの技術に気づいた。

すべては必要に応じて異なります。私はかなり合理的な方法はSystem.currentTimeMillis()を取ることであると確信しています(オプションで、複数回参加またはハッシュすることでそれをプレイできます)。ここで

+0

配列の内容は無関係です。配列はシャッフルされています。つまり、ランダムな順列が生成されてから適用されます。 –

3

は良い記事です: "A Java Programmer’s Guide to Random Numbersは"

基本的には、A)あなたはそれが展示定期的な行動(悪いランダム)であるとしてjava.util.Randomを使用したくない、b)のSecureRandomは、java.util.Randomを超える大きな改善でありますシャッフルしたい要素の数によっては、それが提供する自由度が小さすぎるかもしれません(詳細はthis sectionを参照してください)。また別の問題は、SecureRandomがかなり遅いということです。パフォーマンス上の問題がある場合は、SecureRandomより速いPRNGの代わりに上記のリンクをたどることができます。

関連する問題