.NET 8 里引入了Random.GetItems和RandomNumberGenerator.GetString/RandomNumberGenerator.GetHexString.NET 8 Preview 1 中新增的 random 方法摘要:Getstring/GetHexString的支持,基于 Random 的使用更为方便对于简单的使用场景也比使用RandomNumberGenerator的性能更好一些新引入的 API 定义如下,和方法是类似的,只是的方法是static的,新增的方法是中的实例
在 .NET 10 Preview 3 中为 Random 也引入了
Getstring/GetHexString的支持,基于 Random 的使用更为方便对于简单的使用场景也比使用RandomNumberGenerator的性能更好一些新引入的 API 定义如下,和方法是类似的,只是的方法是static的,新增的方法是中的实例方法 :namespaceSystem;publicpartialclassRandom
{
// same signatures as on RandomNumberGenerator, but instance instead of static
publicstringGetString(ReadOnlySpanchar> choices,intlength);
publicstringGetHexString(intstringLength,boollowercase =false);
publicvoidGetHexString(Spanchar> destination,boollowercase =false);
}
提出 API 的一些描述如下,可以参考 api 提议的 issue:https://github.com/dotnet/runtime/issues/111956
我们为 RandomNumberGenerator 添加了 GetString 和 GetHexString 方法。Random 没有这些方法,但它们在这里同样有用。这些方法与加密安全性并没有太多特定的关系。开发人员需要通过使用 string.Create 然后调用 Random.GetItems 来填充后备空间。如果简单的重载对于 RandomNumberGenerator 是合理的,那么它们对 Random 同样适用。
Sample使用方式和基本一致Console.WriteLine("GetString");varnums ="1234567890";
varrandomString = Random.Shared.GetString(nums,8);
Console.WriteLine(randomString);
Console.WriteLine("GetHexString");
varrandomHexString = Random.Shared.GetHexString(16);
Console.WriteLine(randomHexString);
Console.WriteLine(Random.Shared.GetHexString(16true));
Console.WriteLine("GetHexString Span");
Spanchar> chars =stackallocchar[16];
Random.Shared.GetHexString(chars);
Console.WriteLine(chars);
Random.Shared.GetHexString(chars,true);
如果要在之前的版本里使用,可以使用的 API 来代替Console.WriteLine("RandomNumberGenerator");
varrandString = RandomNumberGenerator.GetString(nums,8);
Console.WriteLine(randString);
Console.WriteLine(RandomNumberGenerator.GetHexString(16));
16true));
RandomNumberGenerator.GetHexString(chars);
Console.WriteLine(chars);
RandomNumberGenerator.GetHexString(chars,true);
输出结果如下:
前面我们提到了性能更好,是否真的如此呢,我们可以做一个简单的 benchmark 来测试一下,benchmark 代码如下:
[ShortRunJob]publicclassBenchmark
{
privatestaticreadonlychar Chars = ['0''1''2''3''4''5''6''7''8''9'];
[Benchmark(Baseline = true)]
publicstringRandomGetString
{
returnRandom.Shared.GetString(Chars,8);
}
[Benchmark]
publicstringRandomNumberGeneratorGetString
{
returnRandomNumberGenerator.GetString(Chars,8);
}
}
benchmark 结果如下:
1. 加密强度更高
RandomNumberGenerator(例如RandomNumberGenerator.GetBytes)基于加密算法(比如 AES 或操作系统提供的 CSPRNG)。这些算法设计目的是不可预测、不可逆、统计上随机,所以它们会消耗更多的CPU 资源。
2. 依赖系统熵源
它通常从系统级熵源读取数据(比如 Linux 的 /dev/urandom或 Windows 的BCryptGenRandom),这会带来额外的I/O 和同步开销。
3. 线程安全和隔离机制
加密用的 RNG 设计时考虑了线程安全、隔离和防止侧信道攻击,因此增加了锁、上下文校验和其他安全逻辑。
4. 不做缓存或简化
和 Random不同,每次都从头生成随机数,不复用种子,不做简化,以保证安全性。
🚀 什么时候应该使用 RandomNumberGenerator?当你需要不可预测的随机数时,就应该使用它。比如:
• 生成密码、API 密钥、Token
• 为密码哈希生成盐值
• 生成加密密钥或 IV
• 生成安全的 Session ID
• 生成 nonce(一次性随机数)
• 任何预测 = 漏洞的情况
🔐 总结:如果你的应用场景中,黑客能猜出“随机数”就会出问题,那就用当你不关心安全,只想要速度快、用法简单时,用Random或 .NET 6+ 的:References• https://github.com/dotnet/runtime/issues/111956
• https://github.com/dotnet/runtime/pull/112162
• https://github.com/WeihanLi/SamplesInPractice/blob/main/net10sample/Net10Samples/RandomSample.cs
• .NET 8 Preview 1 中新增的 Random 方法
来源:opendotnet