最小から最大までの乱数を返すメソッドが必要です。両方の数値が含まれます。Stephen Toub と Shawn Farkas による.NET Matters: Tales from the CryptoRandomという記事でいくつかのコードを見つけました。メソッドは次のようになります。
// Note - maxValue is excluded!
public static int GetRandomIntBetween(int minValue, int maxValue)
{
if (minValue > maxValue) throw new ArgumentOutOfRangeException("minValue");
if (minValue == maxValue) return minValue;
var rng = new RNGCryptoServiceProvider();
var uint32Buffer = new byte[4];
long diff = maxValue - minValue;
while (true)
{
rng.GetBytes(uint32Buffer);
uint rand = BitConverter.ToUInt32(uint32Buffer, 0);
const long max = (1 + (long)int.MaxValue);
long remainder = max % diff;
if (rand < max - remainder)
{
return (int)(minValue + (rand % diff));
}
}
}
maxValue を包括的にしようとする私の試み:
public static int GetRandomIntBetween(int minValue, int maxValue)
{
if (minValue > maxValue) throw new ArgumentOutOfRangeException("minValue");
if (minValue == maxValue) return minValue;
// Make maxValue inclusive.
maxValue++;
var rng = new RNGCryptoServiceProvider();
var uint32Buffer = new byte[4];
long diff = maxValue - minValue;
while (true)
{
rng.GetBytes(uint32Buffer);
uint rand = BitConverter.ToUInt32(uint32Buffer, 0);
const long max = (1 + (long)int.MaxValue);
long remainder = max % diff;
if (rand < max - remainder)
{
return (int)(minValue + (rand % diff));
}
}
}
奇妙に見えますが、最初の 2 つのチェックをそのままにしておくことができ、セマンティックがわずかに異なっていても機能するようです。結果データも良さそうです。私は何かを逃しましたか、それとも私の変更は大丈夫ですか?
PS-乱数の生成は明らかに非常にデリケートな問題であり、私のアプローチが正しいことを確認したいので、これを求めています。