lundi 7 septembre 2015

How should I seed a random engine?

I often see std::random_device used to seed random engines. In libstdc++, it defaults to using IA-32 RDRAND if a hardware RNG is available, otherwise /dev/urandom. libc++ has choices between arc4random(), /dev/urandom and nacl_secure_random. Windows might use RtlGenRandom or the Crypt API.

Of course there are many more options:

Intel-specific:

__asm__ __volatile__ ("rdtsc" : "=a"(lo));

PID:

getpid()

Thread ID:

std::this_thread::get_id()

Using chrono:

std::chrono::high_resolution_clock::now()
                        .time_since_epoch().count();

For libstdc++ this will not always be a nano-second resolution:

#ifdef _GLIBCXX_USE_CLOCK_REALTIME
      timespec tp;
      // -EINVAL, -EFAULT
#ifdef _GLIBCXX_USE_CLOCK_GETTIME_SYSCALL
      syscall(SYS_clock_gettime, CLOCK_REALTIME, &tp);
#else
      clock_gettime(CLOCK_REALTIME, &tp);
#endif
      return time_point(duration(chrono::seconds(tp.tv_sec)
                 + chrono::nanoseconds(tp.tv_nsec)));
#elif defined(_GLIBCXX_USE_GETTIMEOFDAY)
      timeval tv;
      // EINVAL, EFAULT
      gettimeofday(&tv, 0);
      return time_point(duration(chrono::seconds(tv.tv_sec)
                 + chrono::microseconds(tv.tv_usec)));
#else
      std::time_t __sec = std::time(0);
      return system_clock::from_time_t(__sec);
#endif

libc++ has a similar problem:

#ifdef CLOCK_REALTIME
    struct timespec tp;
    if (0 != clock_gettime(CLOCK_REALTIME, &tp))
        __throw_system_error(errno, "clock_gettime(CLOCK_REALTIME) failed");
    return time_point(seconds(tp.tv_sec) + microseconds(tp.tv_nsec / 1000));
#else  // !CLOCK_REALTIME
    timeval tv;
    gettimeofday(&tv, 0); // :(
    return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec));
#endif  // CLOCK_REALTIME

Other options include a hash of compile metadata(__DATE__ __FILE__ __TIME__, as one string), the heap, a hash of address of standard library functions, of a function, of the this pointer, etc. Or some combination of all of them?




Aucun commentaire:

Enregistrer un commentaire