这种生成随机数的方法有多“好”?

我在google上搜索RNGCryptoServiceProvider,其中包含如何限制Max和Min之间范围的示例,并且仍能获得均匀分布。 在我使用模运算符之前,但有时我得到奇怪的值(高于Max)…无论如何这个代码(信用到未知)种子随机使用来自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); } }