为什么要编写自己的随机数生成器?

时间:2015-03-30 13:47:58

标签: java c# c++ random numbers

我已经阅读了很多关于如何编写自己的随机数生成器的指南,所以我对你自己编写自己的原因感兴趣,因为大多数语言已经提供了生成随机数的函数:

与C ++一样

    srand(time(NULL));
    rand();

C#

    Random rand = new Random();
    rand.Next(100);

和Java

    Random rand = new Random();
    rand.nextInt(0, 100);

我主要是在寻找使用自己的优势。

6 个答案:

答案 0 :(得分:2)

如果您已完成研究并发现默认生成器非常糟糕(如C或Excel中的情况,或IBM臭名昭着的randu),您可能有动力下载或实施更好的发电机。但是,除非您对概率,统计和数值方法有非常深刻的理解,否则您在任何情况下都不应尝试创建自己的概率。就像约翰·冯·诺伊曼(John von Neumann)这样的杰出人物已经在这方面搞砸了。

另一个原因可能是获得跨平台的结果再现性。

答案 1 :(得分:2)

永远不要滚动你自己的加密或随机数生成,除非你非常对所涉及的更高数学感到满意。这是一个简短的测试:如果您了解概率分布,线性反馈移位寄存器,不完整伽马函数和中国余数定理,您可能有资格自行推出。

否则,请使用由了解这些内容的人提供的生成器。内置于您的语言中的可能不是。因此,寻找具有良好声誉的附加库。

答案 2 :(得分:1)

可能的原因之一就在你的问题中......:

  

大多数语言已经提供了功能

他们这样做,但他们往往不相容。

我必须写一次,因为我写的(轻量级)加密使用的是与解密(VB)不同的语言(Powerscript),并且它们的Random生成器不兼容。

答案 3 :(得分:1)

有时,即使您需要一系列随机数,您也可能需要相同的随机数序列(用于调试或其他目的)。

在便携式程序中,设计为在具有不同库的不同系统上运行,可能还有不同的随机数生成器,可能无法实现上述目标。

如果你改为实现自己的,你可以控制它,并且可以使它在多个系统上表现相同,而不是依赖于提供的实现。

另外,正如评论中所提到的,提供的实现可能会以某种方式被窃听。

答案 4 :(得分:1)

股票随机数生成器通常是大多数语言中的伪随机数生成器。

伪随机数生成器以某种状态开始,并使用它生成一个看似均匀数字的不可预测的序列。

有许多不同的伪随机数生成器已经研究过。它们有不同的优点和缺点 - 一些更随机,一些具有更长的周期,一些具有加密强度,并且难以从先前的样本中计算出种子,一些是快速的等等。

对于给定语言选择的那个将是对上述特征的一些妥协。在某些情况下,选择的那个将被认为是一个糟糕的,但由于遗留原因,因为“库存”随机数生成器(rand()是一个差的随机数生成器的一个例子)。如果您需要不同于给定语言的随机数生成器选择的重要功能,编写自己的(或找到一个)是获得它的唯一方法。

在某些语言中,随机数生成器(或分发生成器)在指定之下,或者可能在语言的修订版之间发生变化。如果你需要你的随机数生成器的稳定性(比如,你用它来从一个小种子程序生成游戏世界 - 参见经典的游戏星控制2),可能需要自己编写它,即使它是一个克隆您系统上的标准版本。

如果您需要随机数生成器从一种语言稳定到另一种语言,每种语言都会做出不同的选择。

在C ++ 11中,旧的rand()大部分已被弃用,新的​​库包含3个引擎,10个预定义生成器,3个引擎适配器,21个发行版和1个非伪随机数生成器({{ 1}})被添加。分布不明确,而生成器则不是:如果需要交叉编译器兼容给定种子状态的结果,则需要编写自己的分发。

即使在C ++ 11中,有了财富的尴尬,你想要的确切权衡可能无法获得。所以你必须自己编写。

请注意,C ++ 11的生成器集主要是在C ++ 11存在之前编写的。之所以写这篇文章是因为random_device被认为是无用的,人们用自己的随机数生成器编写库。在该版本的C ++中收集和形式化的最佳实践。因此,学习如何编写它们的另一个原因是您需要改进您选择的语言,而程序员则需要这样做。

对于伪随机数生成器属性的深入讨论,wikipedia有一个可接受的起点。这里提到Java的JCG是低质量的。

答案 5 :(得分:-1)

您列出的生成器都是PRNG。这些特定的PRNG不适用于游戏,科学或加密应用程序。