/* * Initialize the default Mersenne Twist PRNG from a 32-bit seed. * * See mts_seed32new for full commentary. */ void mt_seed32new( uint32_t seed) /* 32-bit seed to start from */ { mts_seed32new(&mt_default_state, seed); }
/* * Choose a seed based on a random-number device given by the caller. * If that device can't be opened, use the lower 32 bits from the * current time. */ static void mts_devseed( mt_state* state, /* State vector to seed */ char* seed_dev) /* Device to seed from */ { int bytesread; /* Byte count read from device */ int nextbyte; /* Index of next byte to read */ FILE* ranfile; /* Access to device */ union { char ranbuffer[sizeof (uint32_t)]; /* Space for reading random int */ uint32_t randomvalue; /* Random value for initialization */ } randomunion; /* Union for reading random int */ #ifdef WIN32 struct _timeb tb; /* Time of day (Windows mode) */ #else /* WIN32 */ struct timeval tv; /* Time of day */ struct timezone tz; /* Dummy for gettimeofday */ #endif /* WIN32 */ ranfile = fopen(seed_dev, "rb"); if (ranfile != NULL) { for (nextbyte = 0; nextbyte < (int)sizeof randomunion.ranbuffer; nextbyte += bytesread) { bytesread = fread(&randomunion.ranbuffer[nextbyte], 1, sizeof randomunion.ranbuffer - nextbyte, ranfile); if (bytesread == 0) break; } fclose(ranfile); if (nextbyte == sizeof randomunion.ranbuffer) { mts_seed32new(state, randomunion.randomvalue); return; } } /* * The device isn't available. Use the time. We will * assume that the time of day is accurate to microsecond * resolution, which is true on most modern machines. */ #ifdef WIN32 (void) _ftime (&tb); #else /* WIN32 */ (void) gettimeofday (&tv, &tz); #endif /* WIN32 */ /* * We just let the excess part of the seconds field overflow */ #ifdef WIN32 randomunion.randomvalue = tb.time * 1000 + tb.millitm; #else /* WIN32 */ randomunion.randomvalue = tv.tv_sec * 1000000 + tv.tv_usec; #endif /* WIN32 */ mts_seed32new(state, randomunion.randomvalue); }
/* * Choose a seed based on a random-number device given by the caller. * If that device can't be opened, use the lower 32 bits from the * current time. */ static uint32_t mts_devseed( mt_state* state, /* State vector to seed */ char* seed_dev) /* Device to seed from */ { #ifdef WIN32 dTHX; #endif int bytesread; /* Byte count read from device */ int nextbyte; /* Index of next byte to read */ FILE* ranfile; /* Access to device */ union { char ranbuffer[sizeof (uint32_t)]; /* Space for reading random int */ uint32_t randomvalue; /* Random value for initialization */ } randomunion; /* Union for reading random int */ #ifdef WIN32 struct _timeb tb; /* Time of day (Windows mode) */ #else /* WIN32 */ struct timeval tv; /* Time of day */ #endif /* WIN32 */ ranfile = fopen(seed_dev, "rb"); /* * Some machines have /dev/random but not /dev/urandom. On those * machines, /dev/random is nonblocking, so we'll try it before we * fall back to using the time. */ if (ranfile == NULL) ranfile = fopen(DEVRANDOM, "rb"); if (ranfile != NULL) { setbuf(ranfile, NULL); for (nextbyte = 0; nextbyte < (int)sizeof randomunion.ranbuffer; nextbyte += bytesread) { bytesread = fread(&randomunion.ranbuffer[nextbyte], (size_t)1, sizeof randomunion.ranbuffer - nextbyte, ranfile); if (bytesread == 0) break; } fclose(ranfile); if (nextbyte == sizeof randomunion.ranbuffer) { mts_seed32new(state, randomunion.randomvalue); return randomunion.randomvalue; } } /* * The device isn't available. Use the time. We will * assume that the time of day is accurate to microsecond * resolution, which is true on most modern machines. */ #ifdef WIN32 (void) _ftime (&tb); #else /* WIN32 */ (void) gettimeofday (&tv, NULL); #endif /* WIN32 */ /* * We just let the excess part of the seconds field overflow */ #ifdef WIN32 randomunion.randomvalue = tb.time * 1000 + tb.millitm; #else /* WIN32 */ randomunion.randomvalue = tv.tv_sec * 1000000 + tv.tv_usec; #endif /* WIN32 */ mts_seed32new(state, randomunion.randomvalue); return randomunion.randomvalue; }
/* * Initialize the default Mersenne Twist PRNG from a 32-bit seed. * * See mts_seed32new for full commentary. */ void mt_seed32new( unsigned long seed) /* 32-bit seed to start from */ { mts_seed32new(&mt_default_state, seed); }