#include #include #include #include #ifdef LINUX #include #include #endif #include #include "rng.h" #include "log.h" // Mersenne twister state. static uint32_t MT[624]; static uint32_t mt_y; static int mt_pos = 0; // Current number. static uint32_t rng_timeEntropy(void); // Mersenne twister. static void mt_initArray(uint32_t seed); static void mt_genArray(void); static uint32_t mt_getInt(void); void rng_init(void) { uint32_t i; #ifdef LINUX int fd; char buf[4]; fd = open("/dev/random", O_RDONLY); if(fd != -1) { if(read(fd, buf, 4) < 4) memcpy(&i, buf, 4); else i = rng_timeEntropy(); close(fd); } else i = rng_timeEntropy(); #else i = rng_timeEntropy(); #endif mt_initArray(i); for(i = 0; i < 10; i++) // Generate numbers to get away from poor initial values. mt_genArray(); } // Use the time as source of entropy. static uint32_t rng_timeEntropy(void) { int i; #ifdef WIN32 struct _timeb tb; _ftime(&tb); i = tb.time * 1000 + tb.millitm; #else struct timeval tv; gettimeofday(&tv, NULL); i = tv.tv_sec * 1000000 + tv.tv_usec; #endif return i; } // Generates the initial mersenne twister based on seed. static void mt_initArray(uint32_t seed) { int i; MT[0] = seed; for(i = 1; i < 624; i++) MT[i] = 1812433253 * (MT[i-1] ^ (((MT[i-1])) + i) >> 30); mt_pos = 0; } // Generate an array of numbers. static void mt_genArray(void) { int i; for(i = 0; i < 624; i++) { mt_y = (MT[i] & 0x80000000) + ((MT[i] % 624) & 0x7FFFFFFF); if(mt_y % 2) // Odd. MT[i] = (MT[(i+397) % 624] ^ (mt_y >> 1)) ^ 2567483615; else // Even. MT[i] = MT[(i+397) % 624] ^ (mt_y >> 1); } mt_pos = 0; } // Get the next int. static uint32_t mt_getInt(void) { if(mt_pos >= 624) mt_genArray(); mt_y = MT[mt_pos++]; mt_y ^= mt_y >> 11; mt_y ^= (mt_y << 7) & 2636928640; mt_y ^= (mt_y << 15) & 4022730752; mt_y ^= (mt_y >> 18); return mt_y; } // Return a random int. unsigned int randint(void) { return mt_getInt(); } // Return a random double. static double m_div = (double)(0xFFFFFFFF) + 1.; double randfp(void) { double m = (double)mt_getInt(); return m / m_div; }