c#中生成隨機(jī)數(shù)的五種方法
在 C# 中,生成隨機(jī)數(shù)有多種方式,適用于不同場(chǎng)景。以下是5種主要方法及其對(duì)比:
計(jì)算機(jī)中不存在真正的 "隨機(jī)數(shù)",我們生成的隨機(jī)數(shù)本質(zhì)是偽隨機(jī)數(shù)—— 通過(guò)特定算法和初始條件(種子)計(jì)算出的序列。這些序列看似無(wú)序,但在相同種子下會(huì)完全重復(fù),因此也被稱為 "假隨機(jī)"。
典型使用場(chǎng)景: 注冊(cè)賬號(hào)的驗(yàn)證碼、唯一標(biāo)識(shí)符生成、隨機(jī)點(diǎn)名器、抽獎(jiǎng)系統(tǒng)、游戲中的隨機(jī)事件等。
1. 使用Random類(基礎(chǔ)隨機(jī)數(shù))
特點(diǎn):基于種子的偽隨機(jī)數(shù)生成器,性能較高,適合普通隨機(jī)場(chǎng)景。
示例代碼:
// 創(chuàng)建 Random 實(shí)例(默認(rèn)使用時(shí)間戳作為種子) Random random = new Random(); ? // 生成整數(shù):[minValue, maxValue) int randomInt = random.Next(1, 101); // 生成 1 到 100 之間的隨機(jī)整數(shù) ? // 生成浮點(diǎn)數(shù):[0.0, 1.0) double randomDouble = random.NextDouble(); // 生成 0.0 到 1.0 之間的隨機(jī)小數(shù)
注意事項(xiàng):
種子問(wèn)題:短時(shí)間內(nèi)創(chuàng)建多個(gè)Random實(shí)例可能生成相同序列(因時(shí)間種子相同)。
// 錯(cuò)誤示例:每次循環(huán)創(chuàng)建新實(shí)例,可能生成相同隨機(jī)數(shù) for (int i = 0; i < 5; i++) { Console.WriteLine(new Random().Next(100)); // 可能輸出重復(fù)值 }
解決方案:復(fù)用單個(gè) Random
實(shí)例。
生成隨機(jī)字符: 利用 ASCII 碼范圍生成 a-z 的隨機(jī)字符串(97-122 對(duì)應(yīng)小寫(xiě)字母):
Random random5 = new Random(); string result = ""; for (int i = 0; i < 4; i++) { char c = (char)random5.Next(97, 123); // 生成97-122的隨機(jī)數(shù),轉(zhuǎn)換為字符 result += c; } Console.WriteLine(result); // 例如:"kqzx"
2. 使用System.Random.Shared(線程安全版本)
特點(diǎn):.NET 6+ 引入的靜態(tài)線程安全隨機(jī)數(shù)生成器,無(wú)需手動(dòng)同步。
示例代碼:
// 生成線程安全的隨機(jī)數(shù) int safeRandomInt = Random.Shared.Next(1, 101); // 線程安全的整數(shù) double safeRandomDouble = Random.Shared.NextDouble(); // 線程安全的小數(shù)
優(yōu)勢(shì):
- 無(wú)需擔(dān)心多線程競(jìng)爭(zhēng)問(wèn)題,性能優(yōu)于手動(dòng)加鎖的
Random
。 - 適用于多線程環(huán)境(如并行計(jì)算)。
3. 使用System.Security.Cryptography.RandomNumberGenerator(加密安全隨機(jī)數(shù))
特點(diǎn):使用操作系統(tǒng)的加密隨機(jī)數(shù)生成器,生成高質(zhì)量隨機(jī)數(shù),適用于安全敏感場(chǎng)景(如密碼、令牌生成)。
using System.Security.Cryptography; ? // 生成加密安全的隨機(jī)整數(shù) byte[] buffer = new byte[4]; // 4字節(jié) = 32位整數(shù) using (RandomNumberGenerator rng = RandomNumberGenerator.Create()) { rng.GetBytes(buffer); // 填充隨機(jī)字節(jié) int secureRandomInt = BitConverter.ToInt32(buffer, 0); Console.WriteLine(Math.Abs(secureRandomInt % 100)); // 轉(zhuǎn)換為 0-99 的整數(shù) } ? // 更簡(jiǎn)便的寫(xiě)法(.NET 6+) int secureInt = RandomNumberGenerator.GetInt32(1, 101); // 直接生成 1-100 的整數(shù)
適用場(chǎng)景:
- 密碼學(xué)相關(guān)場(chǎng)景(如生成加密密鑰)。
- 安全令牌、驗(yàn)證碼生成。
4. GUID(全球唯一標(biāo)識(shí)符)
GUID
(Globally Unique Identifier)是 128 位的唯一標(biāo)識(shí)符,通過(guò)系統(tǒng)時(shí)間、硬件 ID 等多維度信息計(jì)算生成,重復(fù)概率極低(可視為全球唯一)。
核心特點(diǎn):
- 格式:
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
(32 位十六進(jìn)制數(shù),含連字符),例如:6F9619FF-8B86-D011-B42D-00C04FC964FF
。 - 生成方式:直接調(diào)用
Guid.NewGuid()
靜態(tài)方法。
適用場(chǎng)景:
生成產(chǎn)品密鑰、訂單號(hào)、數(shù)據(jù)庫(kù)主鍵、分布式系統(tǒng)中的唯一標(biāo)識(shí)等。
Console.WriteLine(Guid.NewGuid()); // 輸出示例:a27fc3ff-f785-4522-bced-7c0f24f0d0e8
5.RNGCryptoServiceProvider(加密級(jí)隨機(jī)數(shù))
屬于加密安全的隨機(jī)數(shù)生成器,基于操作系統(tǒng)底層的加密算法,生成高質(zhì)量隨機(jī)數(shù),適用于安全性要求極高的場(chǎng)景。
核心用法:
通過(guò)字節(jié)數(shù)組接收隨機(jī)數(shù)據(jù),可轉(zhuǎn)換為字符串或數(shù)值使用:
// 創(chuàng)建加密隨機(jī)數(shù)生成器實(shí)例 using (RNGCryptoServiceProvider rcsp = new RNGCryptoServiceProvider()) { byte[] bytes = new byte[10]; // 指定隨機(jī)數(shù)長(zhǎng)度(10字節(jié)) rcsp.GetBytes(bytes); // 生成隨機(jī)字節(jié)并填充到數(shù)組 Console.WriteLine(BitConverter.ToString(bytes)); // 輸出示例:3A-7B-2D-...(十六進(jìn)制格式,以連字符分隔) }
特點(diǎn):
- 隨機(jī)性強(qiáng):基于硬件或系統(tǒng)環(huán)境的熵值(不可預(yù)測(cè)性更高)。
- 線程安全:支持多線程環(huán)境。
- 性能較低:因加密算法復(fù)雜,生成速度慢于
Random
。
適用場(chǎng)景:
密碼加密、令牌生成、敏感數(shù)據(jù)加密密鑰等安全敏感場(chǎng)景。
方法對(duì)比
方法 | 性能 | 線程安全 | 隨機(jī)性質(zhì)量 | 適用場(chǎng)景 |
---|---|---|---|---|
Random | 高 | 否 | 普通(偽隨機(jī)) | 游戲、隨機(jī)排序、普通模擬 |
System.Random.Shared | 高 | 是 | 普通(偽隨機(jī)) | 多線程環(huán)境下的普通隨機(jī)需求 |
RandomNumberGenerator | 低 | 是 | 加密安全(真隨機(jī)) | 密碼學(xué)、安全令牌、敏感數(shù)據(jù) |
GUID | 高 | 中 | 極高(近乎唯一) | 唯一標(biāo)識(shí)(訂單號(hào)、主鍵等) |
RNGCryptoServiceProvider | 極高(加密級(jí)) | 低 | 高 | 安全場(chǎng)景(密碼、密鑰等) |
總結(jié)
- 普通場(chǎng)景:使用
Random
并復(fù)用實(shí)例。 - 多線程場(chǎng)景:使用
System.Random.Shared
。 - 安全敏感場(chǎng)景:使用
RandomNumberGenerator
。
補(bǔ)充說(shuō)明
Random
的擴(kuò)展用法: 生成隨機(jī)字符除了通過(guò) ASCII 碼(97-122 對(duì)應(yīng) a-z),還可直接從字符集抽取:string chars = "qwertyuiopasdfghjklzxcvbnm"; Random ran = new Random(); string res = ""; for (int i = 0; i < 4; i++) { res += chars[ran.Next(chars.Length)]; // 從字符集中隨機(jī)取字符 }
洗牌算法:
GUID
的唯一性: GUID 的唯一性基于 "概率極低",理論上存在重復(fù)可能,但實(shí)際應(yīng)用中可視為絕對(duì)唯一,無(wú)需擔(dān)心沖突。.NET Core/.NET 5 + 的新選擇: 對(duì)于加密隨機(jī)數(shù),推薦使用
RandomNumberGenerator
(.NET 6+)替代RNGCryptoServiceProvider
(已過(guò)時(shí)),用法更簡(jiǎn)潔。// .NET 6+ 推薦寫(xiě)法 byte[] bytes = new byte[10]; RandomNumberGenerator.Fill(bytes); // 填充隨機(jī)字節(jié)
到此這篇關(guān)于c#中生成隨機(jī)數(shù)的三種方法的文章就介紹到這了,更多相關(guān)c# 生成隨機(jī)數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- C#生成指定范圍內(nèi)的不重復(fù)隨機(jī)數(shù)
- C#中獲取、生成隨機(jī)數(shù)的三種方法
- 用C#生成不重復(fù)的隨機(jī)數(shù)的代碼
- C#實(shí)現(xiàn)在兩個(gè)數(shù)字之間生成隨機(jī)數(shù)的方法
- C#中的隨機(jī)數(shù)函數(shù)Random()
- C#生成互不相同隨機(jī)數(shù)的實(shí)現(xiàn)方法
- C#生成隨機(jī)數(shù)的方法小結(jié)
- c#循環(huán)中產(chǎn)生偽隨機(jī)數(shù)
- C#可用于登錄驗(yàn)證碼的四位隨機(jī)數(shù)生成方法
- C# 生成隨機(jī)數(shù)的代碼
相關(guān)文章
C#并發(fā)容器之ConcurrentDictionary與普通Dictionary帶鎖性能詳解
這篇文章主要介紹了C#并發(fā)容器之ConcurrentDictionary與普通Dictionary帶鎖性能詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-04-04unity3D實(shí)現(xiàn)物體任意角度自旋轉(zhuǎn)
這篇文章主要為大家詳細(xì)介紹了unity3D實(shí)現(xiàn)物體任意角度自旋轉(zhuǎn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-07-07C#使用DirectX.DirectSound播放語(yǔ)音
這篇文章主要為大家詳細(xì)介紹了C#使用DirectX.DirectSound播放語(yǔ)音,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03C#實(shí)現(xiàn)連接SQL Server2012數(shù)據(jù)庫(kù)并執(zhí)行SQL語(yǔ)句的方法
這篇文章主要介紹了C#實(shí)現(xiàn)連接SQL Server2012數(shù)據(jù)庫(kù)并執(zhí)行SQL語(yǔ)句的方法,結(jié)合實(shí)例形式較為詳細(xì)的分析了C#連接SQL Server2012數(shù)據(jù)庫(kù)并執(zhí)行查詢、插入等操作的相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-10-10