好吧,我想这完全是主观的,但我正在考虑随机数生成器的熵源。大多数生成器都是以当前时间作为种子的,对吗?好吧,我很好奇还有哪些其他来源可以用来生成完全有效的随机(宽松定义)数字。

使用多个源(例如时间 + 当前 HDD 寻道时间 [我们在这里太梦幻了])一起使用是否会比单个源创建“更随机”的数字?来源数量的逻辑限制是什么?多少才算真正够用?选择时间只是因为方便吗?

抱歉,如果这种事情是不允许的,但我很好奇来源背后的理论。

有帮助吗?

解决方案

维基百科上的文章 硬件随机数发生器 使用物理属性列出了一些有趣的随机数来源。

我最喜欢的:

  • 由连接到 PC 的盖革计数器检测到的核衰变辐射源。
  • 光子穿过半透明镜子。检测到互斥事件(反射-传输)并分别与“0”或“1”位值相关联。
  • 来自电阻器的热噪声被放大以提供随机电压源。
  • 雪崩二极管产生的雪崩噪声。 (多么酷啊?)
  • 大气噪声,由连接到 PC 的无线电接收器检测到

问题部分 维基百科文章的内容还描述了许多此类来源/传感器的脆弱性。随着传感器老化/退化,传感器几乎总是产生逐渐减少的随机数。应通过统计测试不断检查这些物理源,这些测试可以分析生成的数据,确保仪器不会悄无声息地损坏。

其他提示

SGI曾在各种<!>“glob phase <!>”中使用了熔岩灯的照片。作为熵的来源,最终演变成一个名为 LavaRnd 的开源随机数生成器。

我使用 Random.ORG ,他们提供来自大气噪音的免费随机数据,我用它来定期重新播种Mersene-Twister RNG。它几乎是随机的,没有硬件依赖。

不要担心<!>“好<!>”;种子为随机数发生器。序列的统计特性不依赖于如何播种发生器。但是还有其他的事情。担心。请参阅随机数生成中的陷阱

对于硬件随机数发生器,必须测量这些物理源,并且测量过程存在系统误差。你可能会发现<!> quot; pseudo <!> quot;随机数的质量高于<!>“真实的<!>”;随机数。

Linux内核使用设备中断计时(鼠标,键盘,硬盘驱动器)来生成熵。有关熵的维基百科上有一个很好的文章

根据附近种子中的相关性检查现代RNG,并在播种后运行数百次迭代。所以,不幸的是,无聊而又真实的答案是它真的无关紧要。

一般来说,必须检查使用随机物理过程它们是否符合均匀分布,否则会被去除。

在我看来,使用一个非常好理解的伪随机数生成器通常会更好。

我使用了一个加密程序,它使用用户鼠标移动来生成随机数。唯一的问题是程序必须暂停并要求用户随机移动鼠标几秒钟才能正常工作,这可能并不总是实用。

几年前我找到了 HotBits - 数字是由放射性衰变产生的,真的是随机号码。

每天可以下载的数量有限制,但我总是很乐意将它们用作RNG真正随机的种子。

某些TPM(可信平台模块)<!>“chips <!>”;有一个硬件RNG。不幸的是,戴尔笔记本电脑中的(Broadcom)TPM缺乏此功能,但今天出售的许多电脑配备了硬件RNG,使用真正无法预测的量子力学过程。英特尔已经实施了热噪声。

此外,不要仅使用当前时间来为加密目的播种RNG,或者任何不可预测性很重要的应用。从时间开始使用一些低阶位与其他几个源一起使用可能没问题。

类似问题可能对您有用。

抱歉,我迟到了这个讨论(现在已经有 3 1/2 岁了?),但我重新燃起了对 PRN 生成和熵的替代来源的兴趣。Linux 内核开发人员 Rusty Russell 最近对其进行了一次讨论 博客 关于熵的替代来源(除了 /dev/urandom).

但是,我对他的选择并不那么印象深刻。NIC 的 MAC 地址永远不会改变(尽管它与所有其他地址都是唯一的),并且 PID 的可能样本大小似乎太小。

我涉足过 梅森扭转者 (在我的 Linux 机器上)它使用以下算法进行播种。如果有人愿意并且有兴趣,我正在寻求任何评论/反馈:

  1. 创建一个 64 位 + 256 位 * 数量的数组缓冲区 /proc 以下文件。
  2. 将时间戳计数器 (TSC) 值放入该缓冲区的前 64 位中。
  3. 对于以下每一项 /proc 文件,计算 SHA256 总和:

    • /proc/meminfo
    • /proc/self/maps
    • /proc/self/smaps
    • /proc/interrupts
    • /proc/diskstats
    • /proc/self/stat

      将每个 256 位哈希值放入 (1) 中创建的数组中其自己的区域。

  4. 创建整个缓冲区的 SHA256 哈希值。 笔记: 我可以(并且可能应该)使用完全独立于 SHA 函数的不同哈希函数 - 这项技术已被提议作为针对弱哈希函数的“防护措施”。

现在我有 256 位 希望 随机(足够)的熵数据来播种我的 Mersenne Twister。我使用上面的内容填充 MT 数组的开头(624 个 32 位整数),然后使用 MT 作者的代码初始化该数组的其余部分。还有,我 可以 使用不同的哈希函数(例如SHA3​​84、SHA512),但我需要不同大小的数组缓冲区(显然)。

最初的 Mersenne Twister 代码需要一个 32 位种子,但我觉得这远远不够。在当今时代,“仅”运行 2^32-1 个不同的 MT 来寻找破解密码并不超出实际可能性的范围。

我很想阅读任何人对此的反馈。非常欢迎批评。我将捍卫我对 /proc 文件如上所述,因为它们不断变化(尤其是 /proc/self/* 文件,并且 TSC 总是产生不同的值(纳秒[或更好]分辨率,IIRC)。我已经跑了 顽固测试 在此(数百名 十亿 位),而且它似乎表现出色。但这可能更能证明 Mersenne Twister 作为 PRNG 的可靠性,而不是我如何播种它。

当然,这些都不是 完全 不受黑客攻击,但我只是没有看到所有这些(和 SHA*)被黑客攻击 在我的一生中断断续续。

有些人使用键盘输入(按键之间的超时),我听说我认为在小说中可以使用无线电静态接收 - 当然这需要其他硬件和软件......

宇宙微波背景光谱之上的噪声。当然,您必须先删除一些各向异性,前景物体,相关探测器噪声,星系和局部群速度,极化等。许多陷阱仍然存在

种子的来源并不是那么重要。更重要的是伪数生成算法。不过,我不久前听说过有关为某些银行业务生成种子的消息。他们综合考虑了许多因素:

  • 时间
  • 处理器温度
  • 风扇转速
  • 中央处理器电压
  • 我不记得更多了:)

即使其中一些参数随时间变化不大,您也可以将它们放入一些好的哈希函数中。

如何生成好的随机数?

也许我们可以考虑无限多个宇宙?如果这是真的,新的平行宇宙一直在被创造,我们可以这样做:

int Random() {
    return Universe.object_id % MAX_INT;
}

每时每刻我们都应该处于平行宇宙的另一个分支上,所以我们应该有不同的id。唯一的问题是如何获取 Universe 对象:)

如何在一个线程中旋转一个线程,该线程将在一个紧密循环中操纵一些变量一段固定的时间才能被杀死。你最终得到的将取决于处理器速度,系统负载等...非常好,但比srand(时间(NULL))更好......

  

不要担心<!>“好<!>”;种子为随机数发生器。序列的统计特性不依赖于发生器的播种方式。

我不同意 John D. Cook的建议。如果您将Mersenne Twister的种子设置为除了一个之外的所有位,它将最初生成除随机之外的任何数字。生成器需要很长时间才能将此状态转换为可通过统计测试的任何状态。简单地将发生器的前32位设置为种子将产生类似的效果。此外,如果整个状态设置为零,则生成器将产生无穷无尽的零。

正确编写的RNG代码将具有正确编写的种子算法,该算法接受64位值并为发生器播种,因此它将为每个可能的输入产生适当的随机数。因此,如果您使用的是可靠的库,那么任何种子都可以。但如果您将自己的实现混合在一起,那么您需要小心。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top