1

以下のように整数の配列をシャッフルしようとしています、

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

「フィッシャー-イェーツシャッフルを疑似乱数ジェネレーターまたはPRNGで使用すると、追加の問題が発生します。このようなジェネレーターによって出力される数値のシーケンスは、シーケンスの開始時の内部状態によって完全に決定されるため、シャッフルはそのようなものによって駆動されます。ジェネレーターは、ジェネレーターが明確な可能な状態を持っているよりも明確な順列を生成できない可能性があります。... "

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

    byte [] seed = new byte [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;
}
4

2 に答える 2

3

ここに良い記事があります: " A Java Programmer's Guide to Random Numbers "

基本的に、a) 周期的な動作 (ランダム性が悪い) を示すため、そのまま使用したくないjava.util.Random、b) よりSecureRandomも大幅に改善されてjava.util.Randomいるが、シャッフルしたい要素の数によっては、それが提供する自由度は小さすぎます (詳細については、このセクションを参照してください)。また、別の問題は、それSecureRandomが非常に遅いことです。パフォーマンスに問題がある場合は、上記のリンクをたどって、より高速な代替 PRNG を入手できますSecureRandom

于 2012-01-02T15:14:26.383 に答える
0

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

すべてはあなたのニーズ次第です。System.currentTimeMillis() を使用するのが非常に賢明な方法だと思います (オプションで、複数回参加するか、ハッシュすることで操作できます)。

于 2012-01-02T12:57:35.567 に答える