C 一批程序的种子随机数生成器

C 一批程序的种子随机数生成器,c,random,C,Random,因此,通常我会使用类似于: srand(time(0)); 以获得随每次程序调用而变化的伪随机性。然而,我现在的情况是,我有一批程序将同时启动,而且由于时间仅每秒更改一次,因此大多数情况下,我的所有程序都以相同的种子启动 当我希望一组程序同时启动,并且所有程序都得到不同的种子时,有什么更好的策略来播种我的RNG?您可以将时间(0)与其他特定于程序的值相结合。例如,用程序名(argv[0]的适当散列对其进行异或(XOR)通常就足够了),或者甚至仅仅(最好是散列)进程id(如果它们是在同一主机上启

因此,通常我会使用类似于:

srand(time(0));
以获得随每次程序调用而变化的伪随机性。然而,我现在的情况是,我有一批程序将同时启动,而且由于
时间
仅每秒更改一次,因此大多数情况下,我的所有程序都以相同的种子启动

当我希望一组程序同时启动,并且所有程序都得到不同的种子时,有什么更好的策略来播种我的RNG?

您可以将
时间(0)
与其他特定于程序的值相结合。例如,用程序名(
argv[0]
的适当散列对其进行异或(XOR)通常就足够了),或者甚至仅仅(最好是散列)进程id(如果它们是在同一主机上启动的,否则用主机名或IP的散列进行异或)。你甚至可以使用一个哈希值


注意:仅使用进程id进行xoring是非常弱的—如果第二个进程在进程启动时超时,则时间值中翻转的位很容易与两个进程id之间不同的位匹配,从而使生成的种子相同。这就是说,投入与你有多少理由去关心相称的精力….

也许你需要使用
getpid()
以及一些亚秒的时间(也可能是整秒的时间)。也许对这些值进行MD5哈希,然后使用它?使用
getpid()。当然,使用
rand()
很难保证是一个好的随机数生成器。您当然不能将其用于加密。

使用
srand(time(0)^getpid())
按进程特定的值排列种子。这将确保在同一秒内启动的进程具有不同的种子。注意不要将其用于任何“重要”的事情,例如,涉及加密或真实货币

使用“异或”或异或运算符“^”完成置换。因为我们知道同时运行的两个进程必须具有不同的进程ID,所以通过将来自时间(0)的响应与当前PID进行xoring,我们可以确保两个不同的进程不会具有完全相同的种子

请注意,这是一个非常弱的保证,因为我们只是在玩弄一些东西。如果时间精确增加1秒,进程id精确增加一秒,那么在某些情况下,您将得到相同的种子

如果您需要真正不同的随机数种子,那么您需要从/dev/random读取4个字节,然后将其作为整数来为RNG种子


同样,请不要把这个随机数序列用于任何“重要”的事情。重要的是,我指的不仅仅是简单的蒙特卡罗模拟或石头剪刀游戏。

使用更精细的计时器(即系统纳秒计数器)并将其与进程id混合。对于安全应用或蒙特卡罗模拟来说,仍然不够好。使用rdtsc,这是自处理器通电以来的伪周期数。如果你需要更多的保证,用“爱”来异或它。也许可以更深入地了解XOR如何创建新的独特价值+1如果您手头有合适的库,您可能希望使用安全哈希函数(如SHA-1)使您的RNG种子脱离当前时间和进程ID号。如果RNG真的很好,我想这不重要,但我有点担心不同的PID值只相差几位。安全的散列函数实际上是在进行散列运算,即使是输入上的一个位差异也会导致输出上的巨大差异。对于RNG系列的每一个值来说,这可能太耗时了,但仅仅对于种子来说,这应该是可以的。即使使用SHA-1生成种子,熵也不比对time()和getpid()的基本调用多,因此做任何更复杂的事情都是浪费精力。如果OP打算使用srand/random,那么他们能做的最好的事情就是从/dev/random.+1中提取种子,以获得时间(0)^getpid()
的合理且简单的解决方案。它确实有一些问题,尽管
gid
对它有一些可预测性,当然
time(0)
也有一些问题。如果每个程序在代码中都有自己的随机值:
time(0)^getpid()^my\u program\u mask
。我想,在一天结束时,每个程序都需要调用一个真正随机的源。这太棒了。在我的使用中,我实际上只需要getpid(),并且可以完全消除随机数(我只需要来回翻转一点),但是如果将来有人发现这一点,这是一个更完整的答案。