This graph shows which files directly or indirectly include this file:
Go to the source code of this file.
Functions | |
void | SeedRandomNumberGenerator (void) |
double | RandomFloat (double flLow, double flHigh) |
INT32 | RandomINT32 (INT32 lLow, INT32 lHigh) |
double RandomFloat | ( | double | flLow, | |
double | flHigh | |||
) |
Definition at line 148 of file svdrand.cpp.
References genrand(), INT32_MAX_VALUE, and UINT32_MAX_VALUE.
Referenced by ChoosePrimes(), do_kill(), FUNCTION(), GenerateSalt(), move_object(), promote_match(), sane_qsort(), and setup_que().
00149 { 00150 // Validate parameters 00151 // 00152 if (lHigh < lLow) 00153 { 00154 return -1; 00155 } 00156 else if (lHigh == lLow) 00157 { 00158 return lLow; 00159 } 00160 00161 UINT32 x = lHigh-lLow; 00162 if (INT32_MAX_VALUE < x) 00163 { 00164 return -1; 00165 } 00166 x++; 00167 00168 // We can now look for an random number on the interval [0,x-1]. 00169 // 00170 00171 // In order to be perfectly conservative about not introducing any 00172 // further sources of statistical bias, we're going to call getrand() 00173 // until we get a number less than the greatest representable 00174 // multiple of x. We'll then return n mod x. 00175 // 00176 // N.B. This loop happens in randomized constant time, and pretty 00177 // damn fast randomized constant time too, since 00178 // 00179 // P(UINT32_MAX_VALUE - n < UINT32_MAX_VALUE % x) < 0.5, for any x. 00180 // 00181 // So even for the least desireable x, the average number of times 00182 // we will call getrand() is less than 2. 00183 // 00184 UINT32 n; 00185 UINT32 nLimit = UINT32_MAX_VALUE - (UINT32_MAX_VALUE%x); 00186 00187 do 00188 { 00189 n = genrand(); 00190 } while (n >= nLimit); 00191 00192 return lLow + (n % x); 00193 }
void SeedRandomNumberGenerator | ( | void | ) |
Definition at line 46 of file svdrand.cpp.
References bCryptoAPI, bSeeded, CRC32_ProcessBuffer(), CLinearTimeAbsolute::GetUTC(), NUM_RANDOM_UINT32, CLinearTimeAbsolute::Return100ns(), sgenrand(), and sgenrand_from_array().
Referenced by CHashFile::CHashFile(), CHashTable::CHashTable(), dbconvert(), main(), and next_state().
00047 { 00048 if (bSeeded) return; 00049 bSeeded = true; 00050 00051 UINT32 aRandomSystemBytes[NUM_RANDOM_UINT32]; 00052 unsigned int nRandomSystemBytes = 0; 00053 00054 #ifdef HAVE_DEV_URANDOM 00055 // Try to seed the PRNG from /dev/urandom 00056 // If it doesn't work, just seed the normal way 00057 // 00058 int fd = open("/dev/urandom", O_RDONLY); 00059 00060 if (fd >= 0) 00061 { 00062 int len = read(fd, aRandomSystemBytes, sizeof aRandomSystemBytes); 00063 close(fd); 00064 if (len > 0) 00065 { 00066 nRandomSystemBytes = len/sizeof(UINT32); 00067 } 00068 } 00069 #endif // HAVE_DEV_URANDOM 00070 #ifdef WIN32 00071 // The Cryto API became available on Windows with Win95 OSR2. Using Crypto 00072 // API as follows lets us to fallback gracefully when running on pre-OSR2 00073 // Win95. 00074 // 00075 bCryptoAPI = false; 00076 HINSTANCE hAdvAPI32 = LoadLibrary("advapi32"); 00077 if (hAdvAPI32) 00078 { 00079 FCRYPTACQUIRECONTEXT *fpCryptAcquireContext; 00080 FCRYPTRELEASECONTEXT *fpCryptReleaseContext; 00081 FCRYPTGENRANDOM *fpCryptGenRandom; 00082 00083 // Find the entry points for CryptoAcquireContext, CrytpoGenRandom, 00084 // and CryptoReleaseContext. 00085 // 00086 fpCryptAcquireContext = (FCRYPTACQUIRECONTEXT *) 00087 GetProcAddress(hAdvAPI32, "CryptAcquireContextA"); 00088 fpCryptReleaseContext = (FCRYPTRELEASECONTEXT *) 00089 GetProcAddress(hAdvAPI32, "CryptReleaseContext"); 00090 fpCryptGenRandom = (FCRYPTGENRANDOM *) 00091 GetProcAddress(hAdvAPI32, "CryptGenRandom"); 00092 00093 if ( fpCryptAcquireContext 00094 && fpCryptReleaseContext 00095 && fpCryptGenRandom) 00096 { 00097 HCRYPTPROV hProv; 00098 00099 if ( fpCryptAcquireContext(&hProv, NULL, NULL, PROV_DSS, 0) 00100 || fpCryptAcquireContext(&hProv, NULL, NULL, PROV_DSS, CRYPT_NEWKEYSET)) 00101 { 00102 if (fpCryptGenRandom(hProv, sizeof aRandomSystemBytes, 00103 (BYTE *)aRandomSystemBytes)) 00104 { 00105 nRandomSystemBytes = NUM_RANDOM_UINT32; 00106 bCryptoAPI = true; 00107 } 00108 fpCryptReleaseContext(hProv, 0); 00109 } 00110 } 00111 FreeLibrary(hAdvAPI32); 00112 } 00113 #endif // WIN32 00114 00115 if (nRandomSystemBytes >= sizeof(UINT32)) 00116 { 00117 unsigned int i; 00118 for (i = 0; i < nRandomSystemBytes; i++) 00119 { 00120 aRandomSystemBytes[i] &= 0xFFFFFFFFUL; 00121 } 00122 sgenrand_from_array(aRandomSystemBytes, nRandomSystemBytes); 00123 return; 00124 } 00125 00126 // Determine the initial seed. 00127 // 00128 CLinearTimeAbsolute lsaNow; 00129 lsaNow.GetUTC(); 00130 INT64 i64Seed = lsaNow.Return100ns(); 00131 int pid = getpid(); 00132 00133 UINT32 nSeed = CRC32_ProcessBuffer(0, &i64Seed, sizeof(INT64)); 00134 nSeed = CRC32_ProcessBuffer(nSeed, &pid, sizeof(pid)); 00135 00136 if (nSeed <= 1000) 00137 { 00138 nSeed += 22261048; 00139 } 00140 00141 // ASSERT: 1000 < nSeed 00142 00143 sgenrand(nSeed); 00144 }