.Net基礎【擴展】隨機數
阿新 • • 發佈:2017-12-22
進行 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基礎【擴展】隨機數