Инициализация генератора псевдослучайных чисел - dim13/lor GitHub Wiki

Инициализация генератора псевдослучайных чисел зачастую является наболевшим вопросом. Приведу код, который содержит в себе два способа инициализации.

#include <stdio.h>      // printf
#include <stdlib.h>     // random number functions
#include <sys/time.h>       // gettimeofday
#include <limits.h>     // LONG_MAX
#include <math.h>       // floor
#include <unistd.h>     // read
#include <sys/types.h>      // open
#include <sys/stat.h>       // open
#include <fcntl.h>      // open

double dtime(){
    double t;
    struct timeval tv;
    gettimeofday(&tv, NULL);
    t = tv.tv_sec + ((double)tv.tv_usec)/1e6;
    return t;
}

void urandom_ini(){
    double tt = dtime() * 1e6;
    double mx = (double)LONG_MAX;
    srand48((long)(tt - mx * floor(tt/mx)));
}

void dev_random_ini(){
    long r_ini;
    int fd = open("/dev/random", O_RDONLY);
    if(-1 == fd){fprintf(stderr,"Error open /dev/random!\n"); urandom_ini(); return;}
    if(sizeof(long) != read(fd, &r_ini, sizeof(long))){
        fprintf(stderr,"Error read /dev/random!\n"); urandom_ini();
        close(fd); return;
    }
    close(fd);
    srand48(r_ini);
}

int main(int argc, char **argv){
    int i;
    printf("\trandom\t\tdrand48\n");
    dev_random_ini();
    for(i = 0; i < 10; i++){
        printf("\t%ld\t%g\n", random(), drand48());
    }
    printf("\n");
    return 0;
}

Функция dev_random_ini() пытается инициализировать генератор псевдослучайных чисел при помощи сложного генератора ядра, работающего на основе "энтропии" - совокупности большого количества разных псевдослучайных величин (например, движения мышью, нажатия клавиш клавиатуры и т.п.).

Если этот инициализатор не срабатывает, запускается менее надежный инициализатор на основе значения текущего времени.

⚠️ **GitHub.com Fallback** ⚠️