尝试在C中生成随机数,rand()每次编译代码时都不生成不同的数字,任何人都可以告诉我如何使用srand()或告诉我任何其他生成方法。
答案 0 :(得分:11)
为了生成pseudorandom个数字序列,生成器需要为seeded。种子完全决定了将要产生的数字序列。在C中,如您所示,您可以使用srand
播种。根据{{1}}手册页,没有明确的种子意味着生成器将使用1作为种子。这就说明了为什么你总能看到相同的数字(但要记住,序列本身非常随机,质量取决于所使用的生成器,即使每次序列相同)。
用户mzabsky指出,获取对用户感觉随机的种子的一种方法是随着时间播种。另一种常见的方法(我刚刚看到mzabsky也指出 - 抱歉)是使用系统的随机数生成器的内容为生成器播种,该生成器从由鼠标移动,磁盘定时等事物提供的熵池中提取。无法从系统生成器中抽取大量随机性,因为它无法收集足够的熵。但如果您只是从中绘制种子,您将随机选择程序中的一系列随机数。以下是在Linux上使用C语言的示例:
srand(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()
,可以更好地满足您的目的。