Recommended way to initialize srand?

前端 未结 15 1841
夕颜
夕颜 2020-11-22 08:07

I need a \'good\' way to initialize the pseudo-random number generator in C++. I\'ve found an article that states:

In order to generate random-like

15条回答
  •  故里飘歌
    2020-11-22 08:32

    Assuming that the randomness of srand() + rand() is enough for your purposes, the trick is in selecting the best seed for srand. time(NULL) is a good starting point, but you'll run into problems if you start more than one instance of the program within the same second. Adding the pid (process id) is an improvement as different instances will get different pids. I would multiply the pid by a factor to spread them more.

    But let's say you are using this for some embedded device and you have several in the same network. If they are all powered at once and you are launching the several instances of your program automatically at boot time, they may still get the same time and pid and all the devices will generate the same sequence of "random" numbers. In that case, you may want to add some unique identifier of each device (like the CPU serial number).

    The proposed initialization would then be:

    srand(time(NULL) + 1000 * getpid() + (uint) getCpuSerialNumber()); 
    

    In a Linux machine (at least in the Raspberry Pi where I tested this), you can implement the following function to get the CPU Serial Number:

    // Gets the CPU Serial Number as a 64 bit unsigned int. Returns 0 if not found.
    uint64_t getCpuSerialNumber() {
    
        FILE *f = fopen("/proc/cpuinfo", "r");
        if (!f) {
            return 0;
        }
    
        char line[256];
        uint64_t serial = 0;
        while (fgets(line, 256, f)) {
            if (strncmp(line, "Serial", 6) == 0) {
                serial = strtoull(strchr(line, ':') + 2, NULL, 16);
            }
        }
        fclose(f);
    
        return serial;
    }
    

提交回复
热议问题