【问题标题】:Fastest implementation of a true random number generator in C#C#中真随机数生成器的最快实现
【发布时间】:2010-10-14 16:17:29
【问题描述】:

我正在阅读有关 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()" 相比是否更快,是否有一些快速的方法可以获得相同的结果,好吗?

【问题讨论】:

  • 没有“真正的”随机数之类的东西,仅由计算机生成。您的意思是“加密安全”的随机数。
  • public int GetRnd() { return 4; /* 由公平的骰子随机选择。保证随机。 */ }
  • @Princess:链接漫画会更好。
  • 我希望喜欢听听您对“真正的随机数”的定义

标签: c# performance random


【解决方案1】:

还有一点没有提到:

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

我并不是说这样的实现当然一定是加密安全的;只是这样的实现需要 CSPRNG 不提供的 PRNG 的可预测性。

【讨论】:

  • ...当然,Crytographic PRNG 有种子。只是RNGCryptoServiceProvider特别不允许开发者提供。
【解决方案2】:

AFAIK 永远不会在 C# 中实现真正的随机生成器。那只能借助硬件才能做到?

【讨论】:

  • 对于那些对构建或购买自己的基于硬件的真 RNG 不感兴趣的人,您可以使用这个免费站点:random.org,它提供了用于生成真随机数的 web 服务、webform、RESTful 和 HTTP 方法使用大气噪声数据。
【解决方案3】:

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

【讨论】:

  • 当然,它们无处不在,但如果没有专门的设置(如放射源),很难将它们放入软件中。
【解决方案4】:

安全和密码学方面的经验法则:

永远不要自己写。

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

编辑以解决更新后的问题:

当您需要在安全敏感代码中未使用的统计随机数时使用Random.Next,在安全敏感代码中使用RNGCryptoServiceProvider。它没有Random.Next 快,但性能可以接受。您应该进行基准测试以查看实际差异。为了性能而牺牲安全性通常是没有意义的。

【讨论】:

  • 有人能解释一下(这里是初学者)为什么每个人都说“不要自己写吗?”我不认为操作是在写他自己的吗?我以为他只是在问加密安全方法是否与 Random.Next 一样快?
  • 实际上,没关系 - 我认为这只是一个考虑它的警告(当然也是一个很好的警告)。我没有阅读其余的答案,因此没有看到它继续解释使用哪个。
  • Arg - 无法编辑 cmets - “to to” 应改为“not to even”
【解决方案5】:

您首先应该做的是了解RNGPRNGCSPRNG 之间的基本区别。

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

【讨论】:

  • 阅读这些链接 - 不是 PRNG 和 CSPRNG 之间的唯一选择吗?如果一个人确实需要 CSPRNG,那么接下来的考虑是什么?
【解决方案6】:

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

假设 CryptoServiceProvider 实现拥有所有优势。它和 Random.Next 一样快,占用的内存也一样少。

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

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

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

您通常可以假设标准库函数的设计目的是按照包装盒上的说明进行操作并且做得很好。 Random.Next 旨在为您提供伪随机数序列中的下一个随机数尽可能高效地

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

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

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

【讨论】:

  • +1 表示写得好。我喜欢这个答案,因为它提出了“为什么有两种方法?”的问题。和“你如何明智地在每一个之间做出选择?”我想将它链接到几个小时前我问过的一个问题,该问题是关于框架选择的现实世界示例,但不确定如何......
  • 谢谢。我担心它会显得过于苛刻(这不是故意的),我只是想说明框架设计者试图尽可能高效地实现这两个功能,并且可能两者都存在是有原因的。跨度>
【解决方案7】:

您的示例代码生成的“加密安全随机数”只会介于 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 倍。

【讨论】:

  • +1 基准测试结果我会投票两次以获得源链接。
【解决方案8】:

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

我同意 Mehrdad 的意见:不要尝试自己动手。

【讨论】:

  • 引用基于同位素衰变的随机数?我笑了。
  • 哈哈!嗯,有量子随机数生成,不过我不知道它有多便宜。
猜你喜欢
  • 2017-02-27
  • 2023-03-15
  • 1970-01-01
  • 1970-01-01
  • 2012-08-10
  • 2012-11-28
  • 2011-07-03
  • 2016-02-21
相关资源
最近更新 更多