1. 程式人生 > >.Net基礎【擴展】隨機數

.Net基礎【擴展】隨機數

進行 body rup 數據 為我 nbsp gpo string his

隨機數的定義為:產生的所有數字毫無關系.

1.隨機數的原理:

線性同余法:第n+1個數=(第n個數*29+37) % 1000

編寫一個自己的隨機數類:

class MyRand {
    private int seed;
    public MyRand(int seed) {this.seed = seed;} 
  public int Next()
   {
     int next = (seed * 29 + 37) % 1000;
     seed = next;
     return next;
  } 
}

2.Random 類生成隨機數

Random類默認的無參構造函數可以根據當前系統時鐘為種子,進行一系列算法得出要求範圍內的偽隨機數.

Random rd = new Random();
int i = rd.Next();

這種隨機數可以達到一些要求較低的目標,但是如果在高並發的情況下,Random類所取到的系統時鐘種子接近甚至完全一樣,就很有可能出現重復,這裏用循環來舉例

for (int i = 0; i < 10; i++)
{
    Random rd = new Random();  //無參即為使用系統時鐘為種子
    Console.WriteLine(rd.Next().ToString());
}

這個例子會輸出10個相同的"隨機數".

突顯出的問題:因為Random進行偽隨機數的算法是固定的,所以根據同一個種子計算出的數字必然是一樣的.而以當代計算機的運行速度,該循環幾乎是在瞬間完成的,種子一致,所以會出現10次循環輸出同一隨機數的情況.

因此

在For循環中生成多個隨機數的時候要把new Random()放到循環外面。

3.如何生成真隨機數?

在Linux/Unix下可以使用"/dev/random"這個真隨機數發生器,它的數據主來來自於硬件中斷信息。

Windows:CryptGenRandom()函數,主要依據當前進程Id、當前線程Id、系統啟動後的TickCount、當前時間、QueryPerformanceCounter返回的高性能計數器值、用戶名、計算機名、CPU計數器的值等等來計算。

當然.Net下也可以使用RNGCryptoServiceProvider 類(System.Security.Cryptography命名空間下)來生成真隨機數

參考文章:《隨機數是騙人的,.Net、Java、C為我作證》http://www.cnblogs.com/rupeng/p/3723018.html

.Net基礎【擴展】隨機數