我正在寻找在谷歌RNGCryptoServiceProvider对如何限制最大值和最小值之间的范围内的例子,仍然可以得到均匀分布。 以前我用过的模运算,但有时我得到了奇怪的值(上述最大)...反正这个代码(信贷未知)种子随机从RNGCCryptoServiceProvider新的种子,每次调用该方法。 你们有什么感想?
public static int GetRandom(int min, int max)
{
byte[] b = new byte[sizeof(int)];
new System.Security.Cryptography.RNGCryptoServiceProvider().GetBytes(b);
int i = BitConverter.ToInt32(b, 0);
Random r = new Random(i);
return r.Next(min, max);
}
你要创建RNGCryptoServiceProvider
一次对象,然后再使用该对象你想有一个新的随机数每次。 例如,您可以通过说对象插入到GetRandom()
方法或将其存储在类级别的字段。
至于RNGCryptoServiceProvider
类型本身,它自身产生良好的数字,就没有必要创建一个Random
对象,并传递一个种子。 这应该给你一个非常体面的分布:
public static int GetRandom(RNGCryptoServiceProvider rngProvider, int min, int max)
{
byte[] b = new byte[sizeof(UInt32)];
rngProvider.GetBytes(b);
double d = BitConverter.ToUInt32(b, 0) / (double)UInt32.MaxValue;
return min + (int)((max - min) * d);
}
有在使用加密类随机生成种子定期随机生成没有意义的。 (通过最薄弱的环节...的原则),只需使用随机生成的一个实例,并重新使用它:
private static Random rnd = new Random();
public static int GetRandom(int min, int max) {
return rnd.Next(min, max);
}
这是一个更好的做法是种子的随机数生成器只是一个时间在你的应用程序。 我建议你创建一个随机数生成静态类。 随机生成的对象可以仅通过正常使用产生均匀分布。 我不知道什么播种与RNGCryptoServiceProvider发电机的好处。 我更喜欢使用时间,播种方法如常。 因此下面的代码是我的建议:
int randomNumber=Rand.get(min,max);
public static class Rand
{
private static Random rnd;
static rand()
{
rand=new Random(DateTime.Now.Ticks);
}
public static int get(int min,int max)
{
return rnd.Next(min,max);
}
}