萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 網路程式設計 >> 程式語言綜合

C# 產生隨機數的三大方案:Random、Guid 與 RNGCryptoServiceProvider 深度解析

前言:什麼是「真」隨機?

電腦產生的隨機數分為**偽隨機** (演算法產生、可重現) 與**密碼學安全隨機** (熵源驅動、不可預測)。選擇錯誤的類別可能導致安全漏洞或高併發下重複值。

方案一:System.Random — 一般用途偽隨機

var rd = new Random();
int n = rd.Next();            // 0 ~ Int32.MaxValue
int range = rd.Next(1, 100);  // 1 ~ 99

原理:以 Environment.TickCount (系統啟動毫秒數) 為種子。

⚠️ 高併發陷阱

// 短時間內多次 new Random() 會產生相同種子 → 相同序列
for (int i = 0; i < 10; i++)
{
    var r = new Random();
    Console.WriteLine(r.Next()); // 輸出 10 個相同數字
}

解法:共用單一 Random 實例 (注意執行緒不安全) 或改用 ThreadLocal<Random>。

方案二:System.Guid — 全域唯一識別碼

string guid = Guid.NewGuid().ToString();      // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
string compact = Guid.NewGuid().ToString("N"); // 32 位十六進位無分隔

特性:128 位整數,結合 MAC 位址、時間戳記、時鐘序列,極低機率碰撞。

適用:訂單號、資料庫主鍵、分散式系統唯一標識。**不適用**需數值運算或固定長度數字場景。

方案三:RNGCryptoServiceProvider — 密碼學安全隨機數產生器 (CSPRNG)

using (var rng = new RNGCryptoServiceProvider())
{
    byte[] bytes = new byte[16]; // 128 bits
    rng.GetBytes(bytes);
    string hex = BitConverter.ToString(bytes).Replace("-", "");
    // 或轉為整數
    int secureInt = BitConverter.ToInt32(bytes, 0);
}

優勢:使用作業系統熵池 (Windows: CryptGenRandom / Linux: /dev/urandom),高併發下極難重複。

代價:效能較 Random 低 10~100 倍,大量迴圈中會明顯拖慢效能。

補充:Membership.GeneratePassword — 產生含特殊字元的隨機密碼

// 需引用 System.Web.Security
string pwd = Membership.GeneratePassword(length: 20, numberOfNonAlphanumericCharacters: 2);
// 輸出範例: "C!&^HoTNv3!ZHkK9BAbu"

內部同樣使用 CSPRNG,適合產生符合密碼策略的隨機字串。

選型決策表

場景推薦類別理由
遊戲骰子、測試資料、非安全業務邏輯Random (單例/ThreadLocal)效能最佳、API 簡單
資料庫 PK、分散式追蹤 ID、檔案命名Guid全域唯一、無需協調
加密金鑰、Token、重設密碼連結、OAuth stateRNGCryptoServiceProvider / RandomNumberGenerator密碼學安全、抗預測
使用者可閱讀的隨機密碼Membership.GeneratePassword內建字元集與複雜度控制

.NET Core / .NET 5+ 現代化寫法

// 統一介面 RandomNumberGenerator (跨平台)
using (var rng = RandomNumberGenerator.Create())
{
    var bytes = new byte[32];
    rng.GetBytes(bytes);
    // ...
}

// 簡易取得安全隨機整數
int secureRandom = RandomNumberGenerator.GetInt32(Int32.MaxValue);
copyright © 萬盛學電腦網 all rights reserved