C#里的Random

C#里的Random其实有一点小的“问题”,在一定的情况下会出现重复,看如下的代码:

for(int i = 0; i < 100; i ++)
{
    Random rand = new Random();
    Console.WriteLine(rand.Next().ToString());
}
注意输出结果,通常情况下你可以看到输出的内容通常包括大量的相同数据。
在MSDN的解释中,Random标识伪随机数生成器,一种能够产生满足某些随机性统计要求的数字序列的设备。

注意输出结果,通常情况下你可以看到输出的内容通常包括大量的相同数据。

 

MSDN解释

 

在MSDN中的解释中,Random表示伪随机数生成器,一种能够产生满足某些随机性统计要求的数字序列的设备。
伪随机数是以相同的概率从一组有限的数字中选取的。 所选数字并不具有完全的随机性,因为它们是用一种确定的数学算法选择的。

Random 类的当前实现基于 Donald E. Knuth 的减法随机数生成器算法。

 

随机数的生成是从种子值开始。 如果反复使用同一个种子,就会生成相同的数字系列。 产生不同序列的一种方法是使种子值与时间相关,从而对于 Random 的每个新实例,都会产生不同的系列。 默认情况下,Random 类的无参数构造函数使用系统时钟生成其种子值,而参数化构造函数可根据当前时间的计时周期数采用 Int32 值。 但是,因为时钟的分辨率有限,所以,如果使用无参数构造函数连续创建不同的 Random 对象,就会创建生成相同随机数序列的随机数生成器。

 

解决办法

通过将new放在循环外,或尽可能的增加循环的执行时间能够一定程度上的增加生成随机数的“随机性”。

 

其他说明

要生成适合于创建随机密码的加密安全随机数,请使用从 System.Security.Cryptography.RandomNumberGenerator派生的类,如 System.Security.Cryptography.RNGCryptoServiceProvider

 

继承对象

在 .NET Framework 1.0 和 1.1 版中,派生自 Random 的类的最小实现需要重写 Sample 方法,以定义用于生成随机数的新算法或修改算法。 然后,该派生类便可依赖 Random.Next()Random.Next(Int32)Random.Next(Int32, Int32)NextBytesNextDouble 方法的基类实现来调用 Sample 方法的派生类实现。

在 .NET Framework 2.0 及更高版本中,Random.Next()Random.Next(Int32, Int32)NextBytes 方法的行为发生了更改,因此这些方法不必再调用 Sample 方法的派生类实现。 因此,派生自 Random 并且面向 .NET Framework 2.0 及更高版本的类还应重写这三种方法。

posted @ 2011-01-15 21:11  laughter  阅读(847)  评论(1编辑  收藏  举报