3

如何在 C 中为同时运行的多个进程生成随机数?

我想使用srandrand但我不知道如何(也许使用进程 ID?)。

4

2 回答 2

12

您可以根据进程 ID 为每个进程使用不同的种子,例如:

srand(getpid());

然后只需使用rand().

于 2012-09-14T10:28:47.850 回答
1

经过多年因随机种子而导致的奇怪错误,我最终编写了一个代码来获取随机数/dev/urandom,这些随机数与用于 SSL 的随机数相同。在我的代码中,我使用这些“好的”随机数来为 C stdlib rand() 函数播种,只要它有一个好的种子,它就足以完成我的任务:

#include <stdio.h>
#include <stdlib.h>

//HOW MANY BITS IN A CHAR? THIS MACRO IS USUALLY DEFINED
#ifndef CHAR_BIT
#define CHAR_BIT 8
#endif

//PATH TO RANDOM NUMBER GENERATOR
const char inPath[]="/dev/urandom";

//EXTRACTS A PSEUDORANDOM unsigned long FROM THE OPERATING SYSTEM VIA /dev/urandom
unsigned long get_urandom(){

  //OPEN INPUT STREAM
  FILE *inFile;
  inFile=fopen(inPath,"r");

  //FAILED TO OPEN STREAM
  if(inFile==NULL){
    fprintf(stderr, "# Failed to open random device %s\n", inPath);
    return 0;
  }

  //HOW MANY BITS IN A CHAR? HOW MANY CHARS IN AN UNSIGNED LONG?
  const int bitsInChar  = CHAR_BIT;
  const int charsInLong = sizeof(unsigned long) / sizeof(char);

  //GET RANDOM UNSIGNED LONG ONE CHARACTER AT A TIME
  unsigned long randomSeed=0;
  for(int i=0; i<charsInLong; i++)
    randomSeed |= fgetc(inFile) << i*bitsInChar;

  //CLOSE STREAM AND RETURN
  fclose(inFile);
  return randomSeed;

}

int main(){

  // We can use the above function directly to get our random numbers, but this is slow.
  printf("We can get random numbers from the OS via get_urandom: %u\n", get_urandom());  

  // Or we can just call get_urandom once, to use as a seed for the stdlib rand() function.
  unsigned int randomSeed=get_urandom();
  srand(randomSeed);
  printf("Or, using a random seed from get_urandom: %u\n", randomSeed);
  printf("We can get random numbers from stdlib, e.g.: %u\n", rand());
}

这是用 C++ 重写的函数的相同代码:

#include <fstream>
using namespace std;

//HOW MANY BITS IN A CHAR? THIS MACRO IS USUALLY DEFINED
#ifndef CHAR_BIT
#define CHAR_BIT 8
#endif

//EXTRACTS A PSEUDORANDOM unsigned long FROM THE OPERATING SYSTEM VIA /dev/urandom
unsigned long get_urandom(const char inPath[]="/dev/urandom"){

  //OPEN INPUT STREAM
  ifstream inFile(inPath);

  //FAILED TO OPEN STREAM
  if(inFile.fail()){
    fprintf(stderr, "# Failed to open random device %s\n", inPath);
    return 0;
  }

  //HOW MANY BITS IN A CHAR? HOW MANY CHARS IN AN UNSIGNED LONG?
  const int bitsInChar  = CHAR_BIT;
  const int charsInLong = sizeof(unsigned long) / sizeof(char);

  //GET RANDOM UNSIGNED LONG ONE CHARACTER AT A TIME
  unsigned long randomSeed=0;
  for(int i=0; i<charsInLong; i++)
    randomSeed |= inFile.get() << i*bitsInChar;

  //CLOSE STREAM AND RETURN
  inFile.close();
  return randomSeed;

}

int main(){

  // We can use the above function directly to get our random numbers, but this is slow.
  printf("We can get random numbers from the OS via get_urandom: %u\n", get_urandom());  

  // Or we can just call get_urandom once, to use as a seed for the stdlib rand() function.
  unsigned int randomSeed=get_urandom();
  srand(randomSeed);
  printf("Or, using a random seed from get_urandom: %u\n", randomSeed);
  printf("We can get random numbers from stdlib, e.g.: %u\n", rand());
}
于 2012-09-19T00:32:20.333 回答