mux/src/svdrand.h File Reference

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)


Function Documentation

double RandomFloat ( double  flLow,
double  flHigh 
)

INT32 RandomINT32 ( INT32  lLow,
INT32  lHigh 
)

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 }


Generated on Mon May 28 04:40:23 2007 for MUX by  doxygen 1.4.7