C&n的rand()必须是随机的吗?

时间:2017-04-04 06:11:14

标签: c random

我试图获得有关C中rand()的规范和实现的一些信息,但我找不到太多信息。事实上,除了以外我找不到任何东西:

  • rand()不会在函数调用之间前进
  • 相同的种子总是会产生相同的数字
  • 随机数介于0和RAND_MAX
  • 之间

值得注意的是,这些都不需要随机性。具体来说,我没有看到任何禁止此实现的内容:

int randval = 0;

void srand(unsigned int seed) {
    randval = seed;
    return;
}

int rand() {
    return randval++;
}

这似乎有点不合时宜。我缺少一点标准吗?

(另外,用时间()播种rand()是不好的,然后用rand()播种ISAAC?)

3 个答案:

答案 0 :(得分:2)

不仅它不必是随机的,一定不能是随机的,因为它必须是完全确定的:

§7.22.2.2/2

  

srand函数使用该参数作为后续调用rand返回的新伪随机数序列的种子。如果随后使用相同的种子值调用srand,则应重复伪随机数序列。如果在对srand进行任何调用之前调用rand,则应该生成相同的序列,就像第一次使用种子值1调用srand时一样。

如果您需要真正的随机性 - 出于任何加密目的,您可以在Linux(以及大多数其他unices)上使用/dev/random,在Windows上使用CryptGenRandom

如果您对伪随机序列与随机序列类似的程度感兴趣,那就是它statistically random的多少,请参阅@Story Teller's answer

答案 1 :(得分:1)

虽然C标准中的注释不是规范性的,但确实如此:

7.22.2.1 The rand function / note 295

  

不能保证产生的随机序列的质量,并且已知一些实现产生具有令人沮丧的非随机低阶位的序列。具有特殊要求的应用应使用已知足以满足其需求的发电机。

所以你是对的,标准库的完全懒惰的实现看起来像这样。用time播种rand并不坏,它和任何其他种子一样好,并且只要它只播种一次就提供一定程度的随机性。但是,由于缺乏保证,我不会将rand用于任何严肃的申请。

答案 2 :(得分:0)

如POSIX中所述,它不是随机的,而是伪随机的(可重现的和确定的):

  

rand()函数应计算一系列伪随机整数   在[0,{RAND_MAX}]

的范围内

该规范表明它符合ISO-C标准。

显然,你的实现命题并不提供伪随机序列。伪随机生成器的快速定义可以是:"提供均匀分布的生成器",您显然没有提供此类。你的价值观彼此过于平凡。