まったく同時に実行されている複数のプロセスの乱数をCで生成するにはどうすればよいですか?
srand
使用したかったrand
のですが、方法がわかりません(プロセスIDを使用しているのでしょうか?)。
たとえば、プロセス ID に基づいて、プロセスごとに異なるシードを使用できます。
srand(getpid());
そして、ただ使用しますrand()
。
After years and years of weird errors from poor random seeds, I eventually wrote a code to get random numbers from /dev/urandom
, which are the same random numbers used for SSL. In my code I used these "good" random numbers to seed the C stdlib rand() function, which was sufficent for my task as long as it got a good seed:
#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());
}
Here's the same code again with the function rewritten in 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());
}