/* Purpose: a simple random number generator -BEN- */
+#if defined(WINDOWS)
+#include <Windows.h>
+#endif
+
#include "z-rand.h"
/*
* Initialize Xorshift Algorithm state
*/
-static void Rand_Xorshift_init(u32b seed, u32b* state)
+static void Rand_Xorshift_seed(u32b seed, u32b* state)
{
int i;
/*
* Initialize the RNG using a new seed
*/
-void Rand_state_init(u32b seed)
+void Rand_state_set(u32b seed)
+{
+ Rand_Xorshift_seed(seed, Rand_state);
+}
+
+void Rand_state_init(void)
{
- Rand_Xorshift_init(seed, Rand_state);
+#ifdef RNG_DEVICE
+
+ FILE *fp = fopen(RNG_DEVICE, "r");
+
+ do {
+ fread(Rand_state, sizeof(Rand_state[0]), 4, fp);
+ } while ((Rand_state[0] | Rand_state[1] | Rand_state[2] | Rand_state[3]) == 0);
+
+ fclose(fp);
+
+#elif defined(WINDOWS)
+
+ HCRYPTPROV hProvider;
+
+ CryptAcquireContext(&hProvider, NULL, NULL, PROV_RSA_FULL, 0);
+
+ do {
+ CryptGenRandom(hProvider, sizeof(Rand_state[0]) * 4, (BYTE*)Rand_state);
+ } while ((Rand_state[0] | Rand_state[1] | Rand_state[2] | Rand_state[3]) == 0);
+
+ CryptReleaseContext(hProvider, 0);
+
+#else
+
+ /* Basic seed */
+ u32b seed = (time(NULL));
+#ifdef SET_UID
+ /* Mutate the seed on Unix machines */
+ seed = ((seed >> 3) * (getpid() << 1));
+#endif
+ /* Seed the RNG */
+ Rand_state_set(seed);
+
+#endif
}
/*
*
* Could also use rand() from <stdlib.h> directly. XXX XXX XXX
*/
-u32b Rand_external(u32b m)
+s32b Rand_external(s32b m)
{
static bool initialized = FALSE;
static u32b Rand_state_external[4];
{
/* Initialize with new seed */
u32b seed = time(NULL);
- Rand_Xorshift_init(seed, Rand_state_external);
+ Rand_Xorshift_seed(seed, Rand_state_external);
initialized = TRUE;
}