Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <vlCore/Random.hpp>
00033 #include <vlCore/Time.hpp>
00034 #include <vlCore/Log.hpp>
00035 #include <vlCore/MersenneTwister.hpp>
00036 #include <cstdlib>
00037
00038 #if defined(VL_PLATFORM_WINDOWS)
00039 #include <wincrypt.h>
00040 #endif
00041
00042 using namespace vl;
00043
00044
00045 Random::Random()
00046 {
00047 VL_DEBUG_SET_OBJECT_NAME()
00048 #if defined(_MSC_VER) || defined(__MINGW32__)
00049 hCryptProv = NULL;
00050 if( !CryptAcquireContext( (HCRYPTPROV*)&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0) )
00051 hCryptProv = NULL;
00052 #elif defined(__GNUG__) && !defined(__MINGW32__)
00053 mDefURandom = fopen("/dev/urandom", "rb");
00054 #endif
00055 }
00056
00057 Random::~Random()
00058 {
00059 #if defined(_MSC_VER) || defined(__MINGW32__)
00060 if( hCryptProv )
00061 {
00062 CryptReleaseContext( (HCRYPTPROV)hCryptProv, 0 );
00063 hCryptProv = NULL;
00064 }
00065 #elif defined(__GNUG__) && !defined(__MINGW32__)
00066 if (mDefURandom)
00067 {
00068 fclose(mDefURandom);
00069 mDefURandom = NULL;
00070 }
00071 #endif
00072 }
00073
00074 bool Random::fillRandom(void* ptr, size_t bytes) const
00075 {
00076 #if defined(_MSC_VER) || defined(__MINGW32__)
00077 if( !(hCryptProv && CryptGenRandom( (HCRYPTPROV)hCryptProv, bytes, (BYTE*)ptr)) )
00078 {
00079 fillRandomMersenneTwister(ptr, bytes);
00080 return false;
00081 }
00082 else
00083 return true;
00084 #elif defined(__GNUG__) && !defined(__MINGW32__)
00085 if ( mDefURandom && fread(ptr, 1, bytes, mDefURandom) == bytes )
00086 return true;
00087 else
00088 {
00089 fillRandomMersenneTwister(ptr, bytes);
00090 return false;
00091 }
00092 #else
00093 fillRandomMersenneTwister(ptr, bytes);
00094 return false;
00095 #endif
00096 }
00097
00098 void Random::fillRandomMersenneTwister(void* ptr, size_t bytes) const
00099 {
00100 unsigned int rnd = 0;
00101
00102 unsigned char* cptr = (unsigned char*)ptr;
00103 memset(cptr, 0, bytes);
00104 for (size_t i=0; i<bytes; ++i)
00105 {
00106 defMersenneTwister()->randInt( rnd );
00107 cptr[i] ^= (rnd>>0) & 0xFF;
00108 cptr[i] ^= (rnd>>8) & 0xFF;
00109 cptr[i] ^= (rnd>>16) & 0xFF;
00110 cptr[i] ^= (rnd>>12) & 0xFF;
00111 }
00112 }
00113