Source code
Revision control
Copy as Markdown
Other Tools
// RandGen.cpp↩
↩
#include "StdAfx.h"↩
↩
#ifndef _7ZIP_ST↩
#include "../../Windows/Synchronization.h"↩
#endif↩
↩
#include "RandGen.h"↩
↩
#ifndef _WIN32↩
#include <unistd.h>↩
#define USE_POSIX_TIME↩
#define USE_POSIX_TIME2↩
#endif↩
↩
#ifdef USE_POSIX_TIME↩
#include <time.h>↩
#ifdef USE_POSIX_TIME2↩
#include <sys/time.h>↩
#endif↩
#endif↩
↩
// This is not very good random number generator.↩
// Please use it only for salt.↩
// First generated data block depends from timer and processID.↩
// Other generated data blocks depend from previous state↩
// Maybe it's possible to restore original timer value from generated value.↩
↩
#define HASH_UPD(x) Sha256_Update(&hash, (const Byte *)&x, sizeof(x));↩
↩
void CRandomGenerator::Init()↩
{↩
CSha256 hash;↩
Sha256_Init(&hash);↩
↩
#ifdef _WIN32↩
DWORD w = ::GetCurrentProcessId();↩
HASH_UPD(w);↩
w = ::GetCurrentThreadId();↩
HASH_UPD(w);↩
#else↩
pid_t pid = getpid();↩
HASH_UPD(pid);↩
pid = getppid();↩
HASH_UPD(pid);↩
#endif↩
↩
for (unsigned i = 0; i <↩
#ifdef _DEBUG↩
2;↩
#else↩
1000;↩
#endif↩
i++)↩
{↩
#ifdef _WIN32↩
LARGE_INTEGER v;↩
if (::QueryPerformanceCounter(&v))↩
HASH_UPD(v.QuadPart);↩
#endif↩
↩
#ifdef USE_POSIX_TIME↩
#ifdef USE_POSIX_TIME2↩
timeval v;↩
if (gettimeofday(&v, 0) == 0)↩
{↩
HASH_UPD(v.tv_sec);↩
HASH_UPD(v.tv_usec);↩
}↩
#endif↩
time_t v2 = time(NULL);↩
HASH_UPD(v2);↩
#endif↩
↩
#ifdef _WIN32↩
DWORD tickCount = ::GetTickCount();↩
HASH_UPD(tickCount);↩
#endif↩
↩
for (unsigned j = 0; j < 100; j++)↩
{↩
Sha256_Final(&hash, _buff);↩
Sha256_Init(&hash);↩
Sha256_Update(&hash, _buff, SHA256_DIGEST_SIZE);↩
}↩
}↩
Sha256_Final(&hash, _buff);↩
_needInit = false;↩
}↩
↩
#ifndef _7ZIP_ST↩
static NWindows::NSynchronization::CCriticalSection g_CriticalSection;↩
#define MT_LOCK NWindows::NSynchronization::CCriticalSectionLock lock(g_CriticalSection);↩
#else↩
#define MT_LOCK↩
#endif↩
↩
void CRandomGenerator::Generate(Byte *data, unsigned size)↩
{↩
MT_LOCK↩
↩
if (_needInit)↩
Init();↩
while (size != 0)↩
{↩
CSha256 hash;↩
↩
Sha256_Init(&hash);↩
Sha256_Update(&hash, _buff, SHA256_DIGEST_SIZE);↩
Sha256_Final(&hash, _buff);↩
↩
Sha256_Init(&hash);↩
UInt32 salt = 0xF672ABD1;↩
HASH_UPD(salt);↩
Sha256_Update(&hash, _buff, SHA256_DIGEST_SIZE);↩
Byte buff[SHA256_DIGEST_SIZE];↩
Sha256_Final(&hash, buff);↩
for (unsigned i = 0; i < SHA256_DIGEST_SIZE && size != 0; i++, size--)↩
*data++ = buff[i];↩
}↩
}↩
↩
CRandomGenerator g_RandomGenerator;↩