程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> .Net使用system.Security.Cryptography.RNGCryptoServiceProvider類與System.Random類生成隨機數

.Net使用system.Security.Cryptography.RNGCryptoServiceProvider類與System.Random類生成隨機數

編輯:關於.NET

.Net中我們通常使用Random類生成隨機數,在一些場景下,我卻發現Random生成的隨機數並不可靠,在下面的例子中我們通過循環隨機生成10個隨機數:

            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類,但隨機數質量高,可靠性更好。使用哪一種方式視情況而定

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved