在C#中实现最快的真随机数生成器

时间:2009-03-20 23:34:46

标签: c# performance random

我正在阅读Random.Next()关于“适用于创建随机密码的加密安全随机数”的问题,MSDN建议RNGCryptoServiceProvider Class

速度是什么?有一些最快的方法来获得真正的随机数?

编辑: 使用Random.Next(),我得到一个新的随机数。随着......

byte[] randomNumber = new byte[1];
RNGCryptoServiceProvider Gen = new RNGCryptoServiceProvider();
Gen.GetBytes(randomNumber);
int rand = Convert.ToInt32(randomNumber[0]);

我得到一个“加密安全随机数” 我想知道上面的代码是否与“Random.Next()”比较快,如果有一些快速的方法可以得到相同的结果,好吗?

8 个答案:

答案 0 :(得分:45)

回答问题的最简单方法可能是将问题颠倒过来。

假设 CryptoServiceProvider实现具有所有优点。它的速度和Random.Next一样短。

那为什么两个实现都存在? 为什么我们甚至在框架中拥有 Random.Next?

了解我们对每个实施的了解。一个生成加密安全的随机数,另一个不做任何承诺。

哪个更简单?生成随机数,这些随机数足够随机,可用于加密,或生成简单“看起来”随机的数字,但不保证其他任何内容? 如果没有与生成加密安全随机数相关的成本,那么每个随机数生成器都会这样做。

您通常可以假设标准库函数的设计是为了完成它在盒子上所说的并且做得很好。 Random.Next旨在尽可能高效地为您提供伪随机数序列中的下一个随机数

CryptoServiceProvider旨在生成足够强大的随机数,以便在加密中使用,并尽可能高效地 。如果有一种方法可以像Random.Next一样有效地执行此操作,那么Random.Next将使用它

你的问题似乎假设框架设计者的脑损伤 - 他们以某种方式设计了一个不必要的慢函数来生成加密安全的随机数,即使有更快的方法。

生成加密安全随机数的最快方法是最有可能调用专家设计的函数来生成加密安全随机数。

答案 1 :(得分:26)

关于安全性和加密技术的经验法则:

从不自己编写。

采用标准的方式,避免危险的优化。

编辑以解决更新的问题:

当需要安全敏感代码中未使用的统计随机数和安全敏感代码中的Random.Next时,请使用RNGCryptoServiceProvider。它没有Random.Next那么快,但它具有可接受的性能。您应该通过基准来查看实际差异。牺牲性能安全性通常没有意义。

答案 2 :(得分:19)

您的示例代码生成的“加密安全随机数”只会介于0到255之间!

如果要返回所有可能的Int32值,则应使用4个随机字节。您的代码应如下所示:

RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
byte[] rndBytes = new byte[4];
rng.GetBytes(rndBytes);
int rand = BitConverter.ToInt32(rndBytes, 0);

我的(旧式)机器的快速基准测试表明Random.Next比使用RNGCryptoServiceProvider快约200倍。

答案 3 :(得分:7)

您首先应该做的是学习RNGPRNGCSPRNG之间的基本差异。

在此之后,您应该决定您真正需要什么,以及可能的实施方式。但是,作为一般规则,您应该接受已经建立并证明是正确实施的内容。

答案 4 :(得分:5)

在硬件中获取真正随机数的唯一已知方法是缓慢的;如果你试图加快速度,你的头发会变成白色,掉在丛中,NRC会发送机器人来清理服务器机房。

我和Mehrdad在这一方面:不要试图自己动手。

答案 5 :(得分:2)

一个侧面问题,但有趣的是,你在问题中使用“真实”。硬件或软件中不存在真随机数。它们存在于“现实生活中”,如放射性衰变或线路上的噪声,但不能由程序生成。因此,请注意jalf使用“伪”并检查jcinacio的维基百科链接。

答案 6 :(得分:2)

AFAIK永远不会在C#中实现真正的随机生成器。那只能在硬件的帮助下完成吗?

答案 7 :(得分:2)

尚未提出的另一点:

在给定相同的初始种子值的情况下,PRNG将产生可预测的结果。 CSPRNG不会 - 它没有种子价值。这使得PRNG(在某种程度上)适合用于密码流算法。给定相同初始化向量(用作一个或多个PRNG的种子值)的两台计算机可以使用纯文本字节的XORed结果和所使用的种子PNG的输出私下有效地相互通信。

我并没有声称这样的实现当然必须是加密安全的;只有这样的实施才需要CSPRNG不提供的PRNG的可预测性。