【问题标题】:Generate True Random Number Generator in any of programming language以任何编程语言生成真随机数生成器
【发布时间】:2015-07-21 14:49:16
【问题描述】:

根据文档,java.util.Random 不是真正的随机生成器。

从下面的链接:http://docs.oracle.com/javase/7/docs/api/java/util/Random.html,它被引用了


该类的一个实例用于生成伪随机数流。该类使用 48 位种子,使用线性同余公式修改。


我必须实现真随机数生成器。请使用任何编程语言或 java 提出替代方案

【问题讨论】:

  • 从技术上讲,我认为不可能得到任何真正随机的东西,大多数使用某种种子,通常是时间,并使用计算从种子中给出一个“随机”数
  • 对于真正随机的东西,您需要物理外部输入。
  • 你需要一个随机的物理来源。见wikipedia
  • 为什么要实现真正的RNG?
  • 一些处理器提供包含硬件随机值的寄存器,这些输入来自物理波动源。在java中你无法阅读它们。搜索“随机寄存器”

标签: java random


【解决方案1】:

您正试图仅使用 确定性算法 生成一个随机数,该算法用某种编程语言(如 java)表示。在确定性设备中创建真正的随机数生成器是不可能的。

根据确定性的定义,我们知道如果设备配置为相同的状态,它将始终表现出相同的行为。

在真正的随机生成器的特定情况下,该设备将是一种没有输入和一个输出的算法(所需的随机数)。在这种情况下,确定性算法只能产生始终相同的数字。因此不是随机的。

伪随机生成器通过存储内部状态来模拟随机性,用于生成具有随机外观的数​​字序列。从概念上讲,内部状态只是算法的另一个输入,对于相同的内部状态,算法将始终产生相同的输出。尽管这些算法提供了不断变化的数字流,但它们并不是真正随机的,因为它们总是会产生相同的数字串。

您可以尝试通过每次使用不同的值初始化此类伪随机算法的内部状态来进一步改进,从而获得不同的随机数流。但这带来了两个问题:

  • 您从哪里获得初始状态?如果您始终使用相同的初始状态,则不会得到不同的数字流。尝试通过算法(因此确定性地)获得随机状态又是同样的问题。
  • 即使您从物理源获得真正随机的初始状态,数字流仍然不是真正随机的。每个数字都是由先前状态的确定性算法计算得出的。因此,通过检查一长串数字,最终可以知道下一个数字是什么。

实际上可以使用算法创建随机数生成器。您将不得不使用非确定性算法。但是这样的算法本身需要一个随机数生成器才能具有不确定性。例如物理设备或竞争条件。

【讨论】:

  • 如果我没记错的话,Java 在它的一个 API 中使用自系统启动以来的纳秒数的低位,这是非常随机的,实际上不是确定性的。 (启动过程中与温度相关的硬盘速度、随机网络延迟等)
  • 确实如此。但这是一个物理源或随机性:与用户手指耦合的时钟,它按下电源按钮。它不是随机性的算法来源。
  • 是的,但是算法在硬件上运行,如果 java VM 提供这个,那就没问题了。 “实现”也可以包括硬件。而且他必须实现一个强大的随机生成器
  • 完全同意你的看法。您可以在硬件的帮助下实现真正的随机生成器。请注意,硬件中的随机性为 100%,算法中的随机性为 0%。
【解决方案2】:

真的不可能在代码中生成真正的随机数生成器。它必须是随机性的物理来源,即便如此,仍然存在一些关于随机性如何随机到足以被称为真正随机性的问题。

您可以购买各种 USB 随机数生成器,您可以将它们插入并在您的应用程序中获取值。

【讨论】:

    【解决方案3】:

    正如@depperm 评论的那样,这在当前计算机上几乎是不可能的。这也是一个有趣的哲学问题,“真正随机”的概念是否有意义......

    但是,如果您想要比伪随机数生成器“更随机”的东西,您可以让某种“真实世界”事件参与其中。不要向用户索要随机种子——人们不太擅长有意识地“随机”。您可以尝试一些事情(其中任何一个都可以用来“播种”一个伪随机数生成器):

    • 让用户随意移动鼠标,并计算他们的移动;
    • 检查当前时间的低几位(如毫秒或微秒)——尽管取决于系统,它们可能始终为 0,或始终为 16 的倍数,或其他)。
    • https://www.random.org 之类的地方获取一个号码(他们使用大气噪声)

    -s

    【讨论】:

    • Java 中的 SecureRandom 怎么样?它不是像真正的随机生成器那样不可预测吗?它是否使用您提到的任何特殊步骤?
    • docs.oracle.com/javase/7/docs/api/java/security/… 的文档说“许多 SecureRandom 实现都是以伪随机数生成器 (PRNG) 的形式......”另一部分说“任何种子材料都传递给 SecureRandom对象必须是不可预测的”。所以 SecureRandom 通常本身并不是随机的。
    【解决方案4】:

    许多现代计算机都有生成真正随机数的硬件手段。微处理器通常有一条指令,该指令使用反向偏置二极管或一些热噪声放大器来生成随机位并将它们白化,然后将它们传递给操作系统。您还可以购买插入 USB 端口并为您生成随机数的加密狗。

    即使系统没有特定的 RNG 硬件,操作系统也可以从键盘和鼠标计时中收集熵,并根据这些信息提供数字。在 Linux 和 OSX 上,您可以使用 /dev/random 来访问它。在 Windows 上,有 CryptGenRandom()。一个执行良好的 Linux 也会使用处理器的原生 RNG,但有些可能不会。

    除了操作系统,还有像 random.org 这样的网络服务,它从天气数据中生成随机数。

    【讨论】:

    • 您能补充一些参考资料吗?我看到许多公司为此制造专用硬件(其中一些在en.wikipedia.org/wiki/List_of_random_number_generators 列出),但我一直无法找到包含现成 TRNG 或微处理器的通用商用计算机(故意)配备一个。很想知道这些项目。
    • RDRAND 指令存在于所有 Intel Ivy Bridge 和更高版本的芯片中。 Linux 使用它以及其他熵源来制作 /dev/random,这非常好。大多数 32 位和更大的 ARM 芯片也有一个 RNG 子系统,但它们因供应商而异,因此标准 Linux/ARM 不使用它们。例如,在 Beaglebone 上,它以 /dev/hw_random 的形式访问;树莓派有 /dev/hwrng。我没有使用加密狗的经验,所以我不能推荐任何特定的。
    • A well-implemented Linux 没有很好实现的 Linux 怎么办?
    • 除非您使用不起眼的芯片,否则您不太可能遇到这些问题。
    猜你喜欢
    • 1970-01-01
    • 2012-03-18
    • 1970-01-01
    • 1970-01-01
    • 2010-09-10
    • 2013-11-09
    • 2013-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多