代码之家  ›  专栏  ›  技术社区  ›  MoSFeT

GLIBC随机数发生器

  •  1
  • MoSFeT  · 技术社区  · 10 年前

    我明天有一个PRNG演示,必须演示rand()函数的工作原理。

    我找到了一个网站,描述了我所需要的东西,但由于我是C语言初学者,我有几个问题。

    首先,网站是 http://www.mscs.dal.ca/~selinger/random/

    我的问题是:

    • 为什么前三十个数字是模(2^31)-1,其余的是模2^32(从第34个开始)(与sizeof(int)连接)?
    • 为什么第30个数字最后一个是模(2^31)-1,为什么不是31或29,有什么特别的原因吗?
    • 为什么r0…r343被丢弃?
    • 为什么ri+344中最不重要的一位被丢弃了?
    • 为什么选择16807作为乘数?

    我知道有很多关于PRNG的问题,但我找不到这些问题的答案。

    我会在课堂上介绍这个话题,肯定会有人问其中一个问题,我需要一些支持。非常感谢。

    3 回复  |  直到 10 年前
        1
  •  1
  •   user515430    10 年前

    给定一个种子,函数首先使用模数为(2^31)-1的LCG填充一个由34个无符号长字符组成的数组。可以使用任何LCG。此阵列用于LFSR发生器,标签位于3和31,使用加法模2^32。该LFSR的输出通过进行右移以丢弃最低有效位来进行后处理。

    如果阵列的原始状态具有太小的熵(假设几乎所有的数字都为零),则丢弃前344个值以提高数字的质量。假设LFSR的输出满足r_{i}=r_{i-3}+r_{i-31}mod 2^32,这一关系也适用于最低有效位,函数通过丢弃最低有效位来屏蔽这一点。移位还保证了rand的输出是标准要求的正整数。

        2
  •  0
  •   user2076694    10 年前

    你可能会在构建伪随机生成器时读到这篇文章,里面有所有答案。

    选择LCG的周期、乘数等:

    http://en.wikipedia.org/wiki/Linear_congruential_generator

    http://en.wikipedia.org/wiki/Pseudo-random_number_generator

        3
  •  0
  •   MoSFeT    10 年前

    经过一些研究,我发现这个特定的数字(16807和2^31-1)是用来创建一个完整的周期的,也就是说,在这些数字再次出现之前生成0和2^31-1之间的所有数字。注意,2^31-1是梅森素数,16807是本原根模(p);参见费马-欧拉定理-这远远超出了我的范围