gpt4 book ai didi

Perl:rand() 的输出是部分可预测的?

转载 作者:行者123 更新时间:2023-12-04 12:18:48 26 4
gpt4 key购买 nike

我在玩 perl 的 rand() 并注意到当提供大于 2^32 的参数时,输出的最后一位变得可预测。

我发现的最清晰的说明它的方法是使用以下脚本:

srand(); for $i (1..10) { printf "%4x\n",rand(2**48)%2**16 }

每当我执行输出是
5101
6378
2a23
62f2
8d15
effc
9657
2d16
f669
40c0

(这不仅仅是前 10 个值,但我没有看到复制一长串“随机”数字的意义)

对 srand() 的调用是多余的,但它的作用是使提供参数变得容易,并确保它不会改变任何东西。

我试过这个:
  • Debian 挤压具有 perl 5.10 (randbits=48)
  • Debian wheezy 有 perl 5.14 (randbits=48)
  • Debian jessie 具有 perl 5.20 (randbits=48)

  • 我知道 rand() 不应该是加密安全的,但是可预测的最后 16 位比我所理解的更糟糕。我使用的任何功能是否错误?

    最佳答案

    这不仅仅是“默认”种子的实现(srand 不带参数调用或根本不调用),正如您从评论中链接的 Schwern 的回答中可能想到的那样;全部 srand调用(以及初始化 RNG 状态的所有方法)都受此问题的影响。

    目前(从 5.20 开始)perl 使用它自己的基于 FreeBSD 的 RNG 实现 drand48srand48 ;在此之前,perl 使用 drand48srand48如果可用,那么 Linux 上的行为实际上是相同的。在任何一种情况下,srand实现仅使用 32 位输入,将它们置于 48 位 RNG 状态的高 32 位;低 16 位初始化为 0x330e .如果您运行 0x330e通过一轮LCG算法(只需要前一个状态的后16位就可以得到下一个状态的后16位),乘以0xe66d并添加 0x000b ,你最终得到 0x5101这是您观察到的第一个值。

    显然,低位的这种可预测性很糟糕,我不知道为什么没有解决这个问题,尤其是现在 perl 有自己的 RNG 实现,很容易做到 48 位干净。然而,显然它比始终将高位初始化为已知状态的破坏性要小。

    目前,我建议如果你想对 perl 的 RNG 做任何严肃的事情,每次调用最多使用 32 位,如有必要,组合多个调用以获得更高的精度/范围。

    关于Perl:rand() 的输出是部分可预测的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35951189/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com