c - 如何播种 srand() 以避免在大量机器上发生冲突?

标签 c random prng

通常,srand() 的播种是通过以下方式完成的:

srand(time(NULL));

在我的例子中,我使用随机数在网络运行时为我的客户端进程生成一个标识符。该进程有时会重新启动并生成一个新的标识符。随着客户端数量的增加,两个客户端很有可能在同一秒内调用 srand(time(NULL)),这会创建两个相同的标识符,或者服务器端看到的冲突。 Some people suggested a finer resolution :

srand((time.tv_sec * 1000) + (time.tv_usec / 1000));

但这里的问题是种子会每24天左右重复一次,当机器数量足够多时,仍然有碰撞的机会。 There's another solution :

srand(time.tv_usec * time.tv_sec);

但这对我来说似乎也有问题,因为该乘积的模数(高位溢出并被放弃)在 unsigned int 种子值的范围内分布不均。例如,对于每一秒,time.tv_usec == 0 都会产生相同的种子。

那么在我的案例中有没有办法为 srand() 播种?

编辑:客户端在 Linux、Windows、Android 和 iOS 上运行,因此 /dev/random/dev/urandom 并不总是可用。

附言我知道 GUID/UUID 方法,但我想知道在这种情况下是否可以正确地播种 srand()。

最佳答案

srandrand 如果您有许多进程或线程需要在它们之间具有独立的伪随机性,则根本不合适。

在 POSIX 系统上,您可以使用 rand48 函数系列,例如具有已知状态大小的 jrand48。如果你依赖于进程、线程和机器独立性,你应该使用进程 ID、线程 ID、IP 地址和时间中的有效位来初始化状态。 jrand[48] 采用(并修改)三个 short 的状态,因此用不同的数量来播种它们应该相对简单。

除了您列出的一个系统外,其他所有系统都是 POSIX,所以这应该在那里工作。我不知道什么才是适合 Windows 系统的后备方案。

关于c - 如何播种 srand() 以避免在大量机器上发生冲突?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21020418/

相关文章:

tensorflow - 从 TensorFlow 中给定的非均匀分布中进行无放回采样

c++ - 来自随机数生成器包装器 (C++) 的令人困惑的内联行为

java - 加密安全 PRNG(伪随机数生成器)

java - 整数到随机数的稳定映射

c++ - 在 Crypto++ 中将自动播种 PNRG 的输出放入一个字符串中

c - 按 C 顺序查找带元音的单词

c - 警告 : assignment from incompatible pointer type for linklist array

java - 随机替换字符串中随机数的字符

检查用户是否是 C 中的 root 用户?

c - 关于字幕和延迟时间(又一个 C 溢出疑问)