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 <cstdlib>
00036
00037 #if defined(_MSC_VER) || defined(__MINGW32__)
00038 #include <windows.h>
00039 #include <wincrypt.h>
00040
00041
00042 #endif
00043
00044 using namespace vl;
00045
00046
00047 Random::Random()
00048 {
00049 VL_DEBUG_SET_OBJECT_NAME()
00050 #if defined(_MSC_VER) || defined(__MINGW32__)
00051 hCryptProv = NULL;
00052 if( !CryptAcquireContext( (HCRYPTPROV*)&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0) )
00053 hCryptProv = NULL;
00054 #endif
00055 }
00056
00057 Random::~Random()
00058 {
00059 #if defined(_MSC_VER) || defined(__MINGW32__)
00060 if( hCryptProv )
00061 CryptReleaseContext( (HCRYPTPROV)hCryptProv, 0 );
00062 #endif
00063 }
00064
00065 bool Random::fillRandom(void* ptr, size_t bytes) const
00066 {
00067 #if defined(_MSC_VER) || defined(__MINGW32__)
00068 if( !(hCryptProv && CryptGenRandom( (HCRYPTPROV)hCryptProv, bytes, (BYTE*)ptr)) )
00069 {
00070 standardFillRandom(ptr, bytes);
00071 return false;
00072 }
00073 else
00074 return true;
00075 #elif defined(__GNUG__) && !defined(__MINGW32__)
00076 FILE* fin = fopen("/dev/urandom", "rb");
00077 if (fin)
00078 {
00079 if ( fread(ptr, 1, bytes, fin) == bytes )
00080 {
00081 fclose(fin);
00082 return true;
00083 }
00084 }
00085 standardFillRandom(ptr, bytes);
00086 return false;
00087 #else
00088 standardFillRandom(ptr, bytes);
00089 return false;
00090 #endif
00091 }
00092
00093 void Random::standardFillRandom(void* ptr, size_t bytes)
00094 {
00095 unsigned char* cptr = (unsigned char*)ptr;
00096 memset(cptr, 0, bytes);
00097 for (size_t i=0; i<bytes; ++i)
00098 {
00099 unsigned int r = (unsigned int)rand();
00100 cptr[i] ^= (r>>0) & 0xFF;
00101 cptr[i] ^= (r>>8) & 0xFF;
00102 cptr[i] ^= (r>>16) & 0xFF;
00103 cptr[i] ^= (r>>12) & 0xFF;
00104 }
00105
00106 vl::Log::warning("Random::standardFillRandom() is being used.\n");
00107 }
00108
00109 void Random::standardRandomize()
00110 {
00111 Time time;
00112 int stack_pos = 0;
00113 static int static_pos = 0;
00114 int* dyn_pos = new int[10]; delete [] dyn_pos;
00115 unsigned int rand_start = time.microsecond() ^ time.second() ^ time.minute() ^ time.hour() ^
00116 time.dayOfMonth() ^ time.month() ^ time.year() ^
00117 (unsigned long long)&static_pos ^ (unsigned long long)&stack_pos ^ (unsigned long long)dyn_pos;
00118 srand(rand_start);
00119 }
00120