如何在C(Linux)中'随机化()'随机数?

时间:2011-02-08 08:11:15

标签: c

尝试在C中生成随机数,rand()每次编译代码时都不生成不同的数字,任何人都可以告诉我如何使用srand()或告诉我任何其他生成方法。

4 个答案:

答案 0 :(得分:11)

为了生成pseudorandom个数字序列,生成器需要为seeded。种子完全决定了将要产生的数字序列。在C中,如您所示,您可以使用srand播种。根据{{​​1}}手册页,没有明确的种子意味着生成器将使用1作为种子。这就说明了为什么你总能看到相同的数字(但要记住,序列本身非常随机,质量取决于所使用的生成器,即使每次序列相同)。

用户mzabsky指出,获取对用户感觉随机的种子的一种方法是随着时间播种。另一种常见的方法(我刚刚看到mzabsky也指出 - 抱歉)是使用系统的随机数生成器的内容为生成器播种,该生成器从由鼠标移动,磁盘定时等事物提供的熵池中提取。无法从系统生成器中抽取大量随机性,因为它无法收集足够的熵。但如果您只是从中绘制种子,您将随机选择程序中的一系列随机数。以下是在Linux上使用C语言的示例:

srand(3)

根据康拉德迈耶的回答,我想我会详细说明一下。我将随机数的使用分为三类:

  1. 变化。如果您使用随机数在例如游戏中创建看似随机或变化的行为,则无需非常认真地考虑该主题或选择合适的种子。随着时间的推移播种,如果结果不够好,请看一些其他解决方案。在这种情况下,即使相对较差的RNG也会看起来足够随意。
  2. 科学模拟。如果您使用随机数进行科学工作,例如蒙特卡罗计算,则需要注意选择良好生成器。你的种子应该固定(或用户可更改)。你想要变异(在上面意义上);你想要确定性行为,但要有良好的随机性。
  3. 加密。你会非常小心。这可能超出了这个主题的范围。

答案 1 :(得分:8)

这是常用的解决方案:

srand ( time(NULL) );

所有C代码的执行都是确定性的,因此每次调用srand时都必须引入不同的代码。在这种情况下,是时候了。

或者您可以从/dev/random读取数据(打开它就像任何其他文件一样)。

答案 2 :(得分:4)

如果您使用的是不提供/ dev / random的操作系统,请使用如下所示的内容

timeval t1;
gettimeofday(&t1, NULL);
srand(t1.tv_usec * t1.tv_sec);

这段代码可以轻松移植到其他操作系统。

要改善种子,您可以将上面显示的时间产品(可能使用MD5或校验和算法)与主机的MAC地址结合起来。

timeval t1;
gettimeofday(&t1, NULL);
unsigned int seed = t1.tv_usec * t1.tv_sec;

unsigned char mac_addr[6];
getMAC(&mac_addr);
improveSeedWithMAC(&seed, mac_addr) ; // MD5 or checksum ...

srand(seed);

答案 3 :(得分:3)

小心; Linux上的rand(3)联机帮助页指出,某些平台上的rand()实现在低阶位上没有提供良好的随机性。因此,您可能希望使用库来获取实际随机数。 Glib提供了有用的功能,例如g_random_int_range(),可以更好地满足您的目的。