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

Why would you write your own Random Number Generator?

本文关键字:自己的 随机数生成器 为什么      更新时间:2023-10-16

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

像C++

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

C#

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

和Java

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

我主要是想利用你自己的优势。

如果你已经做了研究,发现默认生成器很糟糕(就像C或Excel中的情况,或者IBM臭名昭著的randu),你可能会有动力下载或实现更好的生成器。然而,除非你对概率、统计学和数值方法有很深的理解,否则在任何情况下都不应该尝试创建自己的方法。即使是像约翰·冯·诺依曼这样的名人也在这件事上搞砸了。

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

永远不要使用自己的密码学或随机数生成,除非你对所涉及的高等数学非常熟悉。这里有一个简短的测试:如果你了解概率分布、线性反馈移位寄存器、不完全伽玛函数和中国余数定理,你可能有资格自己滚动。

否则,请使用了解这些内容的人提供的生成器。你的语言中内置的可能不是。所以要寻找声誉良好的附加库。

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

在一个可移植程序中,设计用于在具有不同库的不同系统上运行,可能还有不同的随机数生成器,实现上述目标可能是不可能的。

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

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

您的问题中有一个可能的原因。:

大多数语言已经提供功能

它们确实如此,但它们往往是不相容的。

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

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

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

已经研究了许多不同的伪随机数生成器。它们有不同的优点和缺点——有些更随机,有些周期更长,有些密码很强,很难从以前的样本中计算出种子,有些速度很快,等等

为给定的语言选择的语言将是上述功能的某种折衷。在某些情况下,选择的随机数生成器会被认为是较差的,但由于遗留原因,它被单独作为"库存"随机数生成器(rand()是较差随机数生成器的一个示例)。如果你需要与指定语言随机数生成器不同的功能,那么编写自己的(或找到一个)是获得它的唯一方法

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

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

在C++11中,旧的rand()大多被弃用,并添加了一个新的库,其中包含3个引擎、10个预定义生成器、3个引擎适配器、21个分发版和1个非伪随机数生成器(random_device)。发行版的指定不足,而生成器则没有:如果您需要对给定种子状态的结果进行跨编译器兼容性,则需要编写自己的发行版。

即使在C++11中,有着财富的尴尬,你想要的确切权衡也可能不可用。所以你必须自己写。

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

为了深入讨论伪随机数生成器的属性,维基百科有一个可以接受的起点。这里它提到Java的JCG是一个低质量的JCG。

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