.Net使用system.Security.Cryptography.RNGCryptoServiceProvider类与System.Random类生成随机数
2016-11-29 23:21
405 查看
.Net中我们通常使用Random类生成随机数,在一些场景下,我却发现Random生成的随机数并不可靠,在下面的例子中我们通过循环随机生成10个随机数:
测试生成随时基本都是相同的结果:
很显然上面的结果是不靠谱的,为什么会这样呢,因为微软的Random类,发现在C#中生成随机数使用的算法是线性同余法,这种算法生成的不是绝对随机,而是一种伪随机数,线性同余法算法的的公式是
:第n+1个数 = ( 第N个数 * a + b) % m ,公式中a、b和m分别为常数,是生成随机数的因子,如果之前从未通过同一个Random对象生成过随机数(也就是调用过Next方法),那么第N个随机数为将被指定为一个默认的常数,这个常数在创建一个Random类时被默认值指定,Random也提供一个构造函数允许开发者使用自己的随机数因子.
有人说要将 Random random1 = new Random(); 要放到循环的外面:
测试上面的代码执行的结果是这样的:
得到结果还是不靠谱的
有人说使用GUID产生填充因子:
测试上面的代码得到的结果:
得到的结果还是不靠谱的。
为了生成更加可靠的随机数,微软在System.Security.Cryptography命名空间下提供一个名为system.Security.Cryptography.RNGCryptoServiceProvider的类,它采用系统当前的硬件信息、进程信息、线程信息、系统启动时间和当前精确时间作为填充因子,通过更好的算法生成高质量的随机数,它的使用方法如下所示:
测试结果未发现重复的:
总结:
Random算法简单,性能较高,适用于随机性要求不高的情况,由于RNGCryptoServiceProvider在生成期间需要查询上面提到的几种系统因子,所以性能稍弱于Random类,但随机数质量高,可靠性更好。使用哪一种方式视情况而定
for (int i = 0; i < 10; i++) { Random random1 = new Random(); Console.WriteLine(random1.Next()); }
测试生成随时基本都是相同的结果:
很显然上面的结果是不靠谱的,为什么会这样呢,因为微软的Random类,发现在C#中生成随机数使用的算法是线性同余法,这种算法生成的不是绝对随机,而是一种伪随机数,线性同余法算法的的公式是
:第n+1个数 = ( 第N个数 * a + b) % m ,公式中a、b和m分别为常数,是生成随机数的因子,如果之前从未通过同一个Random对象生成过随机数(也就是调用过Next方法),那么第N个随机数为将被指定为一个默认的常数,这个常数在创建一个Random类时被默认值指定,Random也提供一个构造函数允许开发者使用自己的随机数因子.
有人说要将 Random random1 = new Random(); 要放到循环的外面:
Random random2 = new Random(); for (int i = 0; i < 10; i++) { Console.WriteLine(random2.Next()); }
测试上面的代码执行的结果是这样的:
得到结果还是不靠谱的
有人说使用GUID产生填充因子:
for (int i = 0; i < 10; i++) { byte[] buffer = Guid.NewGuid().ToByteArray(); int iSeed = BitConverter.ToInt32(buffer, 0); Random random3 = new Random(iSeed); Console.WriteLine(random3.Next()); }
测试上面的代码得到的结果:
得到的结果还是不靠谱的。
为了生成更加可靠的随机数,微软在System.Security.Cryptography命名空间下提供一个名为system.Security.Cryptography.RNGCryptoServiceProvider的类,它采用系统当前的硬件信息、进程信息、线程信息、系统启动时间和当前精确时间作为填充因子,通过更好的算法生成高质量的随机数,它的使用方法如下所示:
for (int i = 0; i < 20; i++) { byte[] randomBytes = new byte[8]; System.Security.Cryptography.RNGCryptoServiceProvider rngServiceProvider = new System.Security.Cryptography.RNGCryptoServiceProvider(); rngServiceProvider.GetBytes(randomBytes); int result = BitConverter.ToInt32(randomBytes, 0); result = System.Math.Abs(result); //求绝对值 Console.WriteLine(result); }
测试结果未发现重复的:
总结:
Random算法简单,性能较高,适用于随机性要求不高的情况,由于RNGCryptoServiceProvider在生成期间需要查询上面提到的几种系统因子,所以性能稍弱于Random类,但随机数质量高,可靠性更好。使用哪一种方式视情况而定
相关文章推荐
- (转)使用 .NET 的 RNGCryptoServiceProvider 生成随机数
- [转]使用.net 程序生成 Excel 和Access 文件
- 如何使用.NET生成C#源代码
- .net使用DotNetCharting控件生成报表统计图总结
- 使用Blitz++生成随机数的例子
- .NET使用一般处理程序生成验证码!
- 如何使用.NET生成C#源代码
- .NET使用一般处理程序生成验证码!
- .NET使用一般处理程序生成验证码(网摘学习)
- .Net工具 - 使用动软代码生成器快速生成可分页的GridView
- .NET使用一般处理程序生成验证码!
- .net中使用Random()产生一个随机数
- 在.Net下生成Word文档(已测试可以使用)
- .NET下使用DataAdapter保存数据时,如何生成command语句及使用事务
- .NET使用一般处理程序生成验证码!
- [转]使用.net 程序生成 Excel 和Access 文件
- .NET下使用DataAdapter保存数据时,如何生成command语句及使用事务
- 最简单的.NET生成随机数
- .Net开发必备十大工具详解之使用GhostDoc为代码生成注释文档
- .NET使用DotNetCharting控件生成报表统计图总结