随机数出问题了, 分装了一个
#include <Wincrypt.h>
#include <Realtimeapiset.h>
#include <tchar.h>
#pragma comment(lib,"Advapi32.lib")
class CryptRandom{
CRITICAL_SECTION __lock;
HCRYPTPROV hDefaultProvidor;
std::set<__int64> __szBuffer;
static CryptRandom __instance;
static int iEndTimes;
public:
CryptRandom() throw(){
InitializeCriticalSectionAndSpinCount(&__lock,4000);
::CryptAcquireContext(&hDefaultProvidor, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT);
}
~CryptRandom(){
DeleteCriticalSection(&__lock);
::CryptReleaseContext(hDefaultProvidor, 0);
}
static CryptRandom& getInstance(){
return __instance;
}
//获取随机数, 随便使用
template <typename T>
T getRandomNumer(bool bUseDefaultProvider = true){
EnterCriticalSection(&__lock);
const int iLen = sizeof(T);
unsigned char buffer [iLen] = {0};
int (CryptRandom::*__pFunc)(void * const , const int ) = NULL;
if(bUseDefaultProvider)
__pFunc = &CryptRandom::GetRandBytesWithDefaultProvider;
else
__pFunc = &CryptRandom::GetRandBytes;
if(0 == (this->*__pFunc)(buffer, iLen) ){
T res = *(T*)buffer;
LeaveCriticalSection(&__lock);
return res;
}
__int64 res = getCpuCount();
LeaveCriticalSection(&__lock);
return res;
}
//获取随机种子 , srand 使用
template <typename T>
T getRandomSeed(bool bUseDefaultProvider = true){
EnterCriticalSection(&__lock);
const int iLen = sizeof(T);
unsigned char buffer [iLen] = {0};
int (CryptRandom::*__pFunc)(void * const , const int ) = NULL;
if(bUseDefaultProvider)
__pFunc = &CryptRandom::GetRandBytesWithDefaultProvider;
else
__pFunc = &CryptRandom::GetRandBytes;
T res = 0;
if(0 != (this->*__pFunc)(buffer, iLen) ){
res = getNumberWhenFailed();
LeaveCriticalSection(&__lock);
return res;
}
std::set<__int64>::iterator iter ;
res = *(T*)buffer;
int iTryTimes = 0;
while(1){
iter = __szBuffer.find(res);
if(iter == __szBuffer.end()){
__szBuffer.insert(res);
break;
}
if(++iTryTimes == iEndTimes){
res = getNumberWhenFailed();
break;
}
memset(buffer,0,iLen);
if( 0 != (this->*__pFunc)(buffer,iLen) ){
res = getNumberWhenFailed();
break;
}
res = *(T*)buffer;
}
LeaveCriticalSection(&__lock);
return res;
}
__int64 getCpuCount(){
EnterCriticalSection(&__lock);
LARGE_INTEGER li;
QueryPerformanceCounter(&li);
__int64 res = li.QuadPart;
LeaveCriticalSection(&__lock);
return res;
}
// 没有任何需求, 也可调用此函数;
void GetRandom2(){
FILETIME tmCreation = {0};
FILETIME tmExit = { 0 };
FILETIME tmKernel = { 0 };
FILETIME tmUser = { 0 };
SYSTEMTIME tmSys = { 0 };
GetThreadTimes(GetCurrentThread(), &tmCreation,&tmExit,&tmKernel,&tmUser);
ULARGE_INTEGER tm_total_1 = { 0 };
ULARGE_INTEGER tm_total_2 = { 0 };
FileTimeToLocalFileTime(&tmKernel, &tmKernel);
FileTimeToLocalFileTime(&tmUser, &tmUser);
// FileTimeToSystemTime(&tmCreation, &tmSys);
tm_total_1.HighPart = tmKernel.dwHighDateTime + tmUser.dwHighDateTime;
tm_total_1.LowPart = tmKernel.dwLowDateTime + tmUser.dwLowDateTime;
const uint32_t kPrime1 = 61631;
const uint32_t kPrime2 = 64997;
const uint32_t kPrime3 = 111857;
unsigned int d = kPrime1 * static_cast<uint32_t>(GetCurrentThreadId())
+ kPrime2 * static_cast<uint32_t>(tm_total_1.HighPart )
+ kPrime3 * static_cast<uint32_t>(tm_total_1.LowPart );
}
private:
int GetRandBytes(void * const buffer, const int iLen){
if(NULL == buffer || 0 == iLen )
return -1;
HCRYPTPROV hProvider = 0;
DWORD dwRes =::CryptAcquireContext(&hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT);
if(dwRes == FALSE)
return -1;
dwRes = ::CryptGenRandom(hProvider, iLen, (unsigned char*)buffer);
if(dwRes == FALSE)
return -1;
::CryptReleaseContext(hProvider, 0);
return 0;
}
int GetRandBytesWithDefaultProvider(void * const buffer, const int iLen){
DWORD dwRes = 0;
dwRes = ::CryptGenRandom(hDefaultProvidor, iLen, (unsigned char*)buffer);
if(dwRes == FALSE)
return -1;
return 0;
}
__int64 getNumberWhenFailed(){
__int64 res = 0;
std::set<__int64>::iterator iter ;
while(1){
res = getCpuCount();
iter = __szBuffer.find(res);
if(iter == __szBuffer.end()){
__szBuffer.insert(res);
break;
}
}
return res;
}
};
CryptRandom CryptRandom::__instance;
int CryptRandom::iEndTimes = 3;
int main(int argc, char* argv[])
{
CryptRandom & instance = CryptRandom::getInstance();
for(int i = 0; i < 10 ; ++i)
cout << instance.getRandomNumer<unsigned int>() << ":" << instance.getRandomSeed<unsigned int>() << endl;;
return 0;
}