19

RandomNumberGeneratorの MSDN ドキュメントによると:

アプリケーション コードは、このクラスを直接使用しません。この抽象クラスは、すべての暗号乱数ジェネレーターの基本クラスとして提供されます。

暗号乱数ジェネレーターの実装には、派生クラス RNGCryptoServiceProvider を使用します。

ただし、次のコードがさまざまなコード ベースでいくつかの機会に使用されているのを見てきました。

byte[] bytes = new byte[...];
RandomNumberGenerator rng = RandomNumberGenerator.Create();
rng.GetBytes(bytes);

最も顕著なのはStackExchange (SOが含まれていると思います) とBCrypt.Netです。

したがって、私は少し混乱しています -RandomNumberGenerator上記のコードはどのタイプを返しますか? また、一部のコード ベースがRandomNumberGeneratorではなく使用しているのは、ちょっとした欠陥RNGCryptoServiceProviderですか?

ここRandomNumberGenerator.Create()では完全に欠落しているフードの下でやっていると思いますが、技術的には (抽象クラスであるため)、上記のコードはエラーをスローするべきではありませんか?

4

3 に答える 3

24

RandomNumberGenerator.Create()メソッドは を呼び出しRandomNumberGenerator.Create("System.Security.Cryptography.RandomNumberGenerator")、最終的に のインスタンスを作成しますRNGCryptoServiceProvider

(辞書のペアでいくつかのルックアップを行うため、デフォルトのランダムジェネレーターをどこかに登録することで、その呼び出しの動作を変更できる可能性があります。)

返されるオブジェクトの実際の型はコンパイル時には不明であり、クラスを継承することだけがわかっているため、参照変数をRandomNumberGenerator使用できます。RandomNumberGenerator

入力に応じてさまざまなタイプのインスタンスを作成するこの方法は、WebRequest.Createメソッドなど、フレームワーク内のいくつかの場所で使用されます。


Micrsoft の誰かが、メソッドの現在のドキュメント (フレームワーク 4.5) を「修正」しましたCreate()。それは今言う:

"派生クラスでオーバーライドされると、ランダム データの生成に使用できる暗号乱数ジェネレーターの既定の実装のインスタンスを作成します。"

フレームワーク 4.0 のドキュメントには次のように書かれています。

"ランダム データの生成に使用できる暗号乱数ジェネレーターの既定の実装のインスタンスを作成します。"

これは、メソッドが行うことの正しい説明です。その説明を新しいドキュメントに戻すようリクエストします。

于 2012-09-08T10:26:01.583 に答える
4

のドキュメントRandomNumberGeneratorは基本的にめちゃくちゃです。別の例として、次のようなドキュメントがあります。

派生クラスでオーバーライドされると、暗号乱数ジェネレーターの指定された実装のインスタンスを作成します。

...静的メソッドの場合。静的メソッドはオーバーライドできません。ドキュメントを書いた人は、明らかに考えが正しくありませんでした。

当初の意図は次のようなものだったと思います。

アプリケーション コードは、このクラスを直接インスタンス化しません。この抽象クラスは、すべての暗号乱数ジェネレーターの基本クラスとして提供されます。

Create(静的メソッドを使用して)投稿したコードは完全に合理的だと思います。これは、etc に使用されるのと同じ種類のパターンですXmlReader.Create。静的メソッドは、最も適切な実装を選択します。

于 2012-09-08T10:03:27.857 に答える
2

RandomNumberGenerator.Create静的ファクトリ メソッドです。確かに、派生クラスのインスタンスが返されます。そして、それは抽象的ではないので、これはすべて合法です。

抽象クラスは、より具体的なクラスを使用する代わりに、どこでも使用できるように作成されています。これらは、バージョン管理に適したインターフェイスであることを意図しています。

于 2012-09-08T10:03:38.363 に答える