C 对加密不安全的随机数使用rand()是否可以接受?

C 对加密不安全的随机数使用rand()是否可以接受?,c,random,C,Random,是否可以使用C标准库的rand()函数处理不需要加密的随机数?如果是,还有更好的选择吗?如果没有,应该使用什么 当然,我假设应用。是的,可以使用rand()获取伪随机数。事实上,这就是rand()的全部要点。对于确定的简单任务,您甚至可以为简单性设置系统时钟。除了加密安全性,还有许多系统的rand()具有非常糟糕的随机性属性,如果您需要更好的东西,标准建议是使用非标准的random() rand在许多系统上的不良特性包括: 低阶位中的非随机性(例如,rand()%2保证交替0,1,0,1…)

是否可以使用C标准库的
rand()
函数处理不需要加密的随机数?如果是,还有更好的选择吗?如果没有,应该使用什么


当然,我假设应用。

是的,可以使用
rand()
获取伪随机数。事实上,这就是
rand()
的全部要点。对于确定的简单任务,您甚至可以为简单性设置系统时钟。

除了加密安全性,还有许多系统的
rand()
具有非常糟糕的随机性属性,如果您需要更好的东西,标准建议是使用非标准的
random()

rand
在许多系统上的不良特性包括:

  • 低阶位中的非随机性(例如,
    rand()%2
    保证交替0,1,0,1…)
  • 相对较短的时期,也许“只有”40亿左右
因此,我(不情愿)的建议是,如果您需要“良好”的随机性(比如,对于蒙特卡罗模拟),您可能非常希望使用非标准的替代品来研究
rand()
。(我关于C的一个永恒问题是,为什么任何供应商都会花时间部署一个非标准的
random()
,而不是简单地改进
rand()
。我确实知道标准答案,尽管它们很糟糕。)

另请参见。

rand()
有一些严重的缺点

  • 随机数的质量没有保证。这将因实施情况而异
  • 不同的rand调用使用的共享状态不能保证线程安全
  • 至于POSIX C替代方案,有
    random
    random\u r
    。OpenSSL提供了更先进的生成随机数的方法


    < C++(C++ 11和后)库还提供了许多随机数函数,如果在项目中包含C++是一个选项。

    < P>在主流C标准库中实现 RAND 可能适合于随意使用随机数(例如在大多数单人游戏中,或出于美观目的);尤其是当您的应用程序不关心随机数在时间或计算机上的重复性时。(但请注意,C标准中的
    rand
    规范并未规定
    rand
    交付的数字必须遵循的特定分布。)

    然而,对于更严肃地使用随机数,例如在科学模拟中,我建议您参考我的一篇文章,其中我解释了
    rand
    /
    srand
    的问题是
    rand
    -

    • 使用未指定的RNG算法,但
    • 允许使用
      srand
      对RNG进行初始化,以实现可重复的“随机性”
    这两点合在一起,妨碍了实现改进RNG实现的能力;更改该RNG将无法实现可重复“随机性”的目标,特别是当应用程序由同一供应商升级到较新版本的C运行时库,或者由不同供应商使用库实现编译时。第一点也意味着没有保证随机数的特定质量。另一个问题是
    srand
    只允许相对较小的种子-实际上不超过32位

    然而,即使应用程序不关心可重复的“随机性”,事实上,
    rand
    指定它在默认情况下的行为就像调用了
    srand(1)
    (因此,在实践中,默认情况下会生成相同的“随机”序列)一样,这使得使用
    rand
    比它更难有效地使用

    非密码随机数的更好方法是使用PRNG库-

    • 它使用自包含的PRNG,这些PRNG保持自己的状态(例如,在单个
      结构中),并且不接触全局状态,以及
    • 它实现了一个PRNG算法,应用程序知道该算法的详细信息

    我列出了几个非密码随机数的示例。

    如果不一定要安全,可以使用数字
    9
    。如果想要“随机性”,但不关心密码安全性,则可以使用“是”随机数。@EugeneSh。强制性Dilbert参考:@dbush是的,我想我的选择下意识地受到了这个条带的影响,
    rand()
    的“要点”确实是获得伪随机数,但它因实现不好而臭名昭著,不应不加小心地推荐。即使OP不需要加密安全性,他们的需求也可能不仅仅是坏的
    rand
    实现所提供的。根据C 2018标准,“对于生成的随机序列的质量没有任何保证,一些实现已知会生成具有令人不安的非随机低阶位的序列。”我接受了这个答案,因为它直接回答了这个问题。然而,我也鼓励读者考虑所有其他的答案。Gavin Hoave:不幸的是,当有另外两个有更好和更完整的信息时,你接受了一个糟糕的答案。这个答案很可能会让人误入歧途。@EricPostphil正如我所说,对于简单的任务,
    rand()
    通常已经足够好了。而且,
    rand()
    本身并没有什么不好的地方。与标准库的任何其他部分一样,它的实现可能很差。对于任何更复杂的任务,肯定有更好的选择,但这个具体问题与这些无关。@Ayxan:这个答案缺乏重要信息。而且,
    rand
    与标准库中的大多数其他例程有很大的不同:它们执行它们的功能,即使它们的实现很差。例如,
    strlen<