【问题标题】:Why would you write your own Random Number Generator? [closed]为什么要编写自己的随机数生成器? [关闭]
【发布时间】:2015-06-03 13:38:38
【问题描述】:

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

像 C++

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

C#

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

和Java

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

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

【问题讨论】:

  • 您的问题听起来是基于观点而非技术事实。
  • @TimStoddard 我想这个问题会让你投反对票;因为答案将非常广泛/基于意见。尽管如此:编写您自己的客户 PRNG 的唯一原因可能是:您对现有的属性不满意。含义:你对整个学科有非常深刻的数学理解;你会认为这是一个非常特殊的用例;您将需要一个非常特殊的解决方案。创建 PRNG 的唯一其他原因是学习如何去做。并在这条路线上遇到许多潜在的错误。
  • 我能想到这个问题的技术性、非基于意见的答案。特别是,C++ 中的 Irand 即将被弃用,其背后的原因应记录在各种标准文档中。可以解释 C++11 随机数生成器功能背后的原因,并举例说明 C++11 中未提供的随机数生成器类型。可以添加对 C++11 发行版的讨论,以及您可能想要编写自己的发行版的原因。没有任何强烈的意见依据。你也可以用意见来回答这个问题,但谁在乎呢?
  • @Yakk 但问题仍然非常广泛。询问现有 PNRG 实施的技术细节是一回事。一般来说,谈论“所有人”是完全不同的事情。
  • @ControlAltDel 在编程上下文中,除非上下文另有说明或区别对于尝试做的事情很重要,否则可以理解“随机”表示“伪随机”。

标签: java c# c++ random numbers


【解决方案1】:

其中一个可能的原因就在您的问题中..:

大多数语言已经提供了函数

他们有,但他们往往是不兼容的。

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

【讨论】:

    【解决方案2】:

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

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

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

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

    【讨论】:

      【解决方案3】:

      如果您已完成研究并发现默认生成器很糟糕(例如 C 或 Excel 中的情况,或者 IBM 臭名昭著的 randu),您可能会被激励下载或实施更好的生成器。但是,除非您对概率、统计和数值方法有非常深入的了解,否则在任何情况下都不应尝试创建自己的方法。甚至像约翰·冯·诺依曼这样的杰出人物也在这件事上搞砸了。

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

      【讨论】:

        【解决方案4】:

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

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

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

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

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

        如果您需要随机数生成器在一种语言之间保持稳定,那么每种语言都会做出不同的选择。

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

        即使在 C++11 中拥有如此多的财富,也可能无法获得您想要的确切权衡。所以你必须自己写。

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

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

        【讨论】:

          【解决方案5】:

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

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

          【讨论】:

            【解决方案6】:

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

            【讨论】:

            • 废话。一个好的 PRNG 不仅适用于游戏、模拟、蒙特卡洛集成和其他用途。也存在许多良好的密码安全性。它们很难制作,但远非不可能。
            • @LeeDanielCrocker 我从来没有说过 good PRNG 不适合这些应用程序,只是他列出的那些不适合。我怀疑其他反对者之所以反对我,是因为他们认为我在说什么,而不是我实际说的话。
            • @DavidSchwartz:希望重新措辞能对此有所改善。
            猜你喜欢
            • 2023-03-03
            • 2014-12-31
            • 2018-11-23
            • 2017-03-03
            • 1970-01-01
            • 2014-03-21
            • 1970-01-01
            • 2014-11-17
            • 1970-01-01
            相关资源
            最近更新 更多