RandomクラスのNextメソッドで整数の乱数が取得できます。
Nextメソッドの引数で以下のように取得できます。
Next() | 0 以上の乱数を取得する |
Next(Int32) | 指定した最大値より小さい 0 以上の乱数を取得する |
Next(Int32, Int32) | 指定した範囲内の乱数を取得する |
ただ・・・
RandomクラスをNEWするときに、シード値を渡さなくてもインスタンスできるけど
複数同時にインスタンスが作られた時に、同じ乱数が生成されることがあるみたいです。
なので、同時に乱数を作るときには同じシード値を渡さないように注意が必要です。
それと・・・
microsoftのドキュメントを見ると注釈があり
「擬似乱数は、少数の数値から等しい確率で選択されます。 選択した数値は、数学的アルゴリズムを使用して選択するため、完全にはランダムではありませんが、実用的な目的では十分にランダムです。 」とあります。
うーん、注釈の続きで・・・
「ランダムなパスワードの作成に適したランダムな値など、暗号的に安全な乱数を生成するには、クラスを使用する RNGCryptoServiceProvider か、からクラスを派生させ System.Security.Cryptography.RandomNumberGenerator ます。」とあります。
暗号化などに使う厳密な乱数に使うのでなければ、Randomクラス
暗号化などの厳密な乱数が必要なら、RNGCryptoServiceProviderクラスを使ってね
みたいです。(RNGCryptoServiceProviderクラスは処理が重い見たいです。)
ただ、整数の範囲を指定できるRandomクラスは使い勝手が良いので、RNGCryptoServiceProviderクラスで乱数を作成し、その値をシード値に使ってRandomクラスをNEWするのが良いかと思います。
Randomクラスだけを使ったサンプルとRNGCryptoServiceProviderクラスを組み合わせたサンプルを以下に作成しました。
プログラミング
言語:C#
/// <summary>
/// 疑似乱数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
// シード値用の値
int s = 0;
// Randomクラス
Random random1 = new System.Random(s++);
Random random2 = new System.Random(s++);
Random random3 = new System.Random(s++);
// 0 以上の乱数を取得する
int rand1 = random1.Next();
Console.WriteLine($"0 以上のランダムな整数 : {rand1} ");
// 指定した最大値より小さい 0 以上の乱数を取得する
int rand2 = random2.Next(50);
Console.WriteLine($"指定した最大値より小さい 0 以上のランダムな整数 : {rand2} ");
// 指定した範囲内の乱数を取得する
int rand3 = random3.Next(1, 50);
Console.WriteLine($"指定した範囲内のランダムな整数 : {rand3} ");
}
/// <summary>
/// RNGCryptoServiceProviderを使用した乱数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object sender, EventArgs e)
{
for (int i = 0; i < 3; i++)
{
// RNGCryptoServiceProviderクラス
RNGCryptoServiceProvider rNGCryptoServiceProvider = new RNGCryptoServiceProvider();
// 暗号乱数を格納するbyte配列(32ビット分)
byte[] cryptRand = new byte[4];
// 暗号乱数を取得する
rNGCryptoServiceProvider.GetBytes(cryptRand);
// 暗号乱数をbyte配列から整数に変換する
int s = System.BitConverter.ToInt32(cryptRand, 0);
// RNGCryptoServiceProviderクラスのシード値に暗号乱数を渡しインスタンス化する
Random random = new System.Random(s);
// 1~100の乱数を取得する
int rand = random.Next(1, 100);
Console.WriteLine($"指定した範囲内のランダムな整数 : {rand} ");
}
}
実行結果
Randomクラスだけを使ったサンプルの結果
ちゃんと乱数出来てますね。
・RNGCryptoServiceProviderクラスを組み合わせたサンプルの結果
こちらも見た目では厳密かわかりませんが、できてますね!
より厳密な乱数・・・とか出てきて、乱数は結構奥が深そうな感じです。