Random は線形合同ジェネレーターです。つまり、次の形式の式に基づいています。
N <- (N * C1 + C2) % M
ここで、C1、C2、および M は定数です。
このクラスのジェネレーターの特性の 1 つは、自己相関が高いことです。実際、連続する数値をプロットすると、数値に明確な剥ぎ取りパターンが見られます。
テスト プログラムは、基礎となるジェネレーターから 10 個の連続した数値を効果的に取得し、それらの値を 10 を法として計算し、それらがすべて同じであることを発見しました。事実上、モジュロ 10 は発電機の自然な周期性と "共鳴" しています ... 短期間です。
これは、自己相関の高い PRNG を使用することの欠点の 1 つです。素人の言葉で言うと...「あまりランダムではない」...ランダム性が重要な状況で使用すると、問題が発生する可能性があります。
ノート:
- Random は乱数ジェネレーターではありません。疑似乱数ジェネレーターです。つまり、初期状態がわかっている場合、生成される数値は完全に予測可能です。
- ランダムに真のランダムシードを使用しても、実際には役に立ちません。問題の再現が難しくなるだけです。
- この特定のテストで同様のパターンが得られる Random の他のシードがある可能性があります。
- 純粋に数学的な観点からは、10 の 1 は、他の 10 の数列と同じように「ランダム」ではありません。しかし、数学的な観点から
Random
は、まったくランダムではありません。実際、 の現在の値が何であるかがわかれば、完全に予測可能N
です。問題は、シーケンスが直感的に非ランダムに見える自己相関です。
- この種の直感的な非ランダム性を回避したい場合は、真の乱数ソースであるか、予測がはるかに困難な疑似乱数のジェネレーターである SecureRandom を使用してください。