System.Security.Cryptography.RNGCryptoServiceProvider
とSystem.Random
を使用する場合の長所と短所は何ですか。私はRNGCryptoServiceProvider
が「よりランダム」であること、つまりハッカーが予測しにくいことを知っています。他の長所または短所はありますか?
UPDATE:
回答によると、これまでにRNGCryptoServiceProvider
を使用する場合の長所と短所があります。
RNGCryptoServiceProvider
はより強力な暗号化乱数であり、暗号化キーなどを決定するのに適しています。Random
は単純な計算であるため、高速です。暗号のランダム性が重要ではないシミュレーションや長い計算で使用する場合は、これを使用する必要があります。注:シミュレーションの詳細については Kevinの回答 を参照してください-Random
は必ずしも十分にランダムではなく、別の非暗号化PRNGを使用する必要がある場合があります。暗号学的に強力なRNGは遅くなります---計算量が多くなります---スペクトルは白になりますが、シミュレーションやモンテカルロ法にはあまり適していませんdoがかかるためより多くの時間、そしてそれらは再現性がないかもしれないので、これはテストにとって素晴らしいことです。
一般に、暗号化PRNGは、UUIDのような一意の番号が必要な場合、または暗号化のキーとして使用し、決定論的なPRNGスピードとシミュレーション。
System.Random
はスレッドセーフではありません。
はい、あと1つだけです。チャーリー・マーティンが書いたようにSystem.Random
はより高速です。
次の情報を追加したいと思います。
RNGCryptoServiceProvider
は、セキュリティ標準に準拠した乱数ジェネレータのデフォルトの実装です。セキュリティの目的でランダム変数が必要な場合は、このクラスまたは同等のクラスを使用する必要がありますが、System.Randomは予測可能性が高いため使用しないでください。
他のすべての用途では、System.Random
の同等のパフォーマンスと同等のクラスを使用できます。
以前の回答に加えて:
System.Random
は、[〜#〜]絶対に使用しないでください[〜#〜]科学および工学のシミュレーションまたは数値ソルバーで使用する必要があります。不正確なシミュレーション結果または収束の失敗。これは、Microsoftの実装にはいくつかの点で重大な欠陥があり、互換性の問題のために簡単に修正できない(または修正できない)ためです。 -- この投稿 を参照してください。
そう:
生成されたシーケンスを知らないはずの敵がいる場合、RNGCryptoServiceProvider
または慎重に設計、実装、検証された、暗号学的に強力なRNGを使用し、理想的にはハードウェアを使用する可能な場合はランダム性。 その他の場合]
良い統計的特性を必要とするシミュレーションなどのアプリケーションの場合、慎重に設計および実装された非暗号を使用しますPRNG such Mersenne Twister 。(これらの場合、crypto RNGも正しいですが、遅くて扱いにくいことが多いです。)その他の場合]
[〜#〜] only [〜#〜]数値の使用が完全に取るに足らない場合(次に表示する画像を決定するなど)ランダム化されたスライドショーで、System.Random
を使用します。
最近、医療機器のさまざまな使用パターンの影響をテストすることを目的としたモンテカルロシミュレーションで作業しているときに、この問題に非常にはっきりと遭遇しました。シミュレーションの結果は、予想されていたものの反対方向の穏やかな結果でした。
説明できない場合は、その背後に理由があり、その理由は非常に面倒な場合があります!
以下は、シミュレーションバッチの数を増やして取得したp ‑値のプロットです。
赤とマゼンタのプロットは、調査中の2つの出力メトリックにおける2つの使用モデル間の差の統計的有意性を示しています。
シアンのプロットは、シミュレーションに対するランダムなinputの特性のp ‑ valuesを表すため、特に衝撃的な結果です。 (これは、入力に誤りがないことを確認するためだけにプロットされています。)もちろん、入力は調査中の2つの使用モデル間で同じに設計されていたため、入力に統計的有意差はなかったはずです。 2つのモデルに。しかし、ここでは、99.97%以上の信頼性がwasあると確信しています。
最初はコードに問題があると思っていましたが、すべてチェックアウトされました。 (特に、スレッドがSystem.Random
のインスタンスを共有していないことを確認しました。)テストを繰り返してこの予期しない結果の一貫性が高いことがわかったとき、System.Random
の疑いを持ち始めました。
私はSystem.Random
をMersenne Twister実装に置き換えました—他の変更はありません—次のように、すぐに出力が大幅に異なりました。
このグラフは、この特定のテストセットで使用されているパラメーターの2つの使用モデル間に統計的に有意な差がないことを反映しています。これは予期された結果でした。
最初のグラフでは、垂直ログスケール(p ‑ value)はseven decadesをカバーしていますが、10年しかありません。 2番目に」-偽の不一致の統計的有意性がどれほど顕著であったかを示しています。 (縦軸は、不一致が偶然に生じた可能性を示しています)。
何が起こっていたのかと思いますが、System.Random
は、かなり短いジェネレータサイクルで相関関係があり、テスト対象の2つのモデル間で内部ランダム性サンプリングのパターンが異なります(Random.Next
への呼び出し数が大幅に異なっていました)。これらが2つのモデルに異なる方法で影響を及ぼしました。
シミュレーションinputがモデルが内部決定に使用するのと同じRNGストリームから描画されることがあり、これにより、これらのサンプリングの不一致が入力に影響を与えたようです。 (これは実際には幸運なことでした。そうでなければ、予期しない結果がソフトウェアの障害であり、シミュレートされているデバイスの実際の特性ではないことに気付かなかったかもしれません。)