RNGCryptoServiceProvider的优点和缺点

时间:2009-01-07 01:04:36

标签: c# .net random

使用System.Security.Cryptography.RNGCryptoServiceProvider vs System.Random的优缺点是什么?我知道RNGCryptoServiceProvider'更随机',即黑客无法预测。还有其他任何利弊吗?


更新

根据回复,以下是目前使用RNGCryptoServiceProvider的优缺点:

赞成

  • RNGCryptoServiceProvider是一个更强大的加密随机数,这意味着它可以更好地确定加密密钥等。

缺点

  • Random更快,因为它是一个更简单的计算;当在模拟或长时间计算中使用加密随机性不重要时,应该使用它。注意:有关模拟的详细信息,请参阅Kevin's answer - Random不一定是随机的,您可能希望使用其他非加密PRNG。

4 个答案:

答案 0 :(得分:51)

加密强RNG会慢一些 - 需要更多的计算 - 并且会是光谱白色,但不适合模拟或蒙特卡罗方法,因为它们花费更多时间,因为它们可能不可重复,这对测试很有帮助。

通常,当您需要唯一的数字(如UUID)或加密密钥以及速度和模拟的确定性PRNG时,您希望使用加密PRNG。

答案 1 :(得分:12)

System.Random不是线程安全的。

答案 2 :(得分:9)

是的,只有一个。正如查理·马丁写的System.Random更快。

我想添加以下信息:

RNGCryptoServiceProvider是符合安全标准的随机数生成器的默认实现。如果出于安全目的需要随机变量,则必须使用此类或等效项,但不要使用System.Random,因为它具有高度可预测性。

对于所有其他用途,欢迎使用System.Random和等效类的更高性能。

答案 3 :(得分:2)

除了先前的答案:

System.Random不应从不用于科学和工程的模拟或数值求解器,因为模拟结果不正确或收敛失败会带来严重的负面影响。这是因为Microsoft的实现在多个方面存在严重缺陷,并且由于兼容性问题,他们无法(或不会)轻松地对其进行修复。请参见this post

所以:

  • 如果有一个对手不知道所生成的序列,则使用RNGCryptoServiceProvider或其他经过精心设计,实施和验证的具有加密功能的强RNG,并且理想情况下使用硬件随机性可能。 否则;

  • 如果它是诸如模拟之类的应用程序,需要良好的统计属性,则请使用经过精心设计和实现的非加密PRNG,例如Mersenne Twister。 (在这种情况下,加密的RNG也正确,但通常太慢且笨拙。)否则;

  • (例如,确定数字的使用非常简单),例如确定随机幻灯片中接下来要显示的图片,然后使用{{1} }。


我最近在从事旨在测试医疗设备不同使用模式的效果的蒙特卡洛仿真时非常切实地遇到了这个问题。模拟产生的结果与合理预期的相反方向温和地出现。

  

有时您无法解释某些内容,背后有一个原因,而这个原因可能非常繁琐!

下面是在越来越多的模拟批次中获得的 p -值的图:

Input & output _p_‑values while using <code>System.Random</code>

红色和品红色图表显示了所研究的两个输出指标中两种用法模型之间差异的统计显着性。

青色图是一个特别令人震惊的结果,因为它表示模拟的随机 input 特征的 p -值。 (这只是为了确认输入不是错误而绘制的。)当然,输入是通过设计来研究的两个使用模型之间相同的,因此输入<之间应该没有任何统计学上的显着差异/ em>到两个模型。但是在这里,我看到的信心强于99.97%( )!

最初,我认为我的代码中有问题,但是一切都已签出。 (特别是我确认线程没有共享System.Random实例。)当重复测试发现此意外结果高度一致时,我开始怀疑System.Random

我将System.Random替换为MersenneTwister实现-没有其他更改,-输出立即变得截然不同,如下所示:

Input & output _p_‑values after switching to a better PRNG

此图反映了在此特定测试集中使用的参数的两种用法模型之间在统计上没有显着差异。这是预期的结果。

请注意,在第一个图表中,垂直对数刻度(在 p 值上)涵盖了七个十年,而第二个图表中只有一个十年证明伪造差异的统计意义多么明显! (垂直刻度表示出现差异的可能性是通过机会产生的。)

我怀疑正在发生的事情是,System.Random在相当短的生成器周期上具有一些相关性,并且两个被测模型之间的内部随机性采样方式不同(对{{1 }})导致它们以不同的方式影响两个模型。

碰巧的是,仿真输入来自与模型用于内部决策的相同RNG流,这显然导致了这些采样差异影响输入。 (这实际上是一件幸运的事,因为否则我可能没有意识到意外的结果是软件故障,而不是被仿真设备的某些真实属性!)