【问题标题】:Generate truly random numbers with C++ (Windows 10 x64)使用 C++ (Windows 10 x64) 生成真正的随机数
【发布时间】:2021-12-30 11:39:44
【问题描述】:

我正在尝试创建密码生成器。我使用了random 库,在阅读文档后,我发现rand() 依赖于算法和种子(srand())来生成随机数。我尝试使用当前时间作为种子(srand(time(0))),但这并不是真正随机的。有没有办法生成真正的随机数?或者可能非常准确地获取当前时间(例如,以微秒为单位)?我的平台是 Windows 10 x64。

【问题讨论】:

  • 请参阅qrng.anu.edu.au,尽管这比通过 C++ 标准库提供给您的方法要慢几个数量级。
  • 您最好使用操作系统的加密随机数生成器 api 或使用 openssl 或 crypto++ 之类的库

标签: c++ random


【解决方案1】:

不,这些不是真正的随机数。真正的随机性需要硬件支持。通常,它们通过对模拟生成的白噪声信号进行采样来工作。

您可能希望使用始终不同的值来播种随机生成器。一个 time() 调用可以做到这一点,或者您也可以通过当前 pid ( getpid() ) 对其进行哈希处理。

【讨论】:

  • 什么是pid?是否需要任何库才能找到它?
  • 请注意,这个“总是不同的种子”意味着每次运行应用程序时使用一次,而不是每次检索到的随机数使用一次。
  • 进程的进程id。它是一个整数。在任务管理器的详细信息视图中有一个列。
  • @xDev120: 一个好的 PRNG(伪随机数生成器)将播种,并通过对其生成函数的一系列连续调用,生成一系列数字缺乏非随机特征,因此无法进行预测(除非您知道确切的算法)。但是,如果您每次都重新播种算法,则算法每次都会重新开始。使用 time() 进行这种重新播种是一个常见错误,并且可以让攻击者猜测使用的算法,从而猜测下一个数字。您基本上违背了 PRNG 的目的。
  • (ctd.) PRNG 质量下降到种子源质量时的质量,并且 time() 是非随机的。
【解决方案2】:

确实,没有专用硬件,PC 无法生成真正的随机数,但请记住,每台 PC 都至少连接了一个硬件随机生成器 - 该设备就是您,坐在计算机前的用户。人是一个非常随机的东西。每个人都有自己的按键速度、鼠标移动模式等。这可以为您带来优势。

在 Linux 上,你有一个特殊的设备,/dev/random,它正是使用这个。当您在 PC 上工作时,它会收集随机数据(当然对安全不敏感),例如您敲击键盘的速度,以及与硬件相关的数据,例如中断间隔和一些磁盘 IO 信息。这一切都会产生熵,后来被用来生成伪随机数据,它仍然不是 100% 随机的,而是基于更强的随机种子。

我不是 Windows 专家,但快速搜索显示 Windows 提供了CryptGenRandom API,功能有些相似。

如果你想生成加密性强的随机数据,我建议你从这个开始。请记住,这仍然不如专用硬件随机发生器强大。但这对于大多数现实世界的用例来说已经足够了。

【讨论】:

    【解决方案3】:

    如果您根据您的问题使用rand() 生成密码,那么我建议您使用某种加密方法,因为它们比rand() 生成的数字更强大且抗冲突。使用类似 Openssl 的东西或类似的东西。

    如果不是,那么“peterh”所建议的真正随机数需要硬件支持。然而,您可以使用比rand() 更好的功能,例如Mersenne Twister。它是一个比 rand() 更好的生成器,因为 rand 只使用了一个简单的linear congruential generator。了解 mt_19937 here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-17
      • 1970-01-01
      • 2013-11-09
      • 2013-10-06
      • 2017-08-15
      • 2013-06-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多