/* */ #include "SimpleRandomizer.h" #include #include #include #include #include #include "a2time.h" #include "a2functional.h" #ifdef HAVE_GETRANDOM_INTERFACE # include "getrandom_linux.h" #endif namespace aria2 { std::unique_ptr SimpleRandomizer::randomizer_; const std::unique_ptr& SimpleRandomizer::getInstance() { if(!randomizer_) { randomizer_.reset(new SimpleRandomizer()); } return randomizer_; } SimpleRandomizer::SimpleRandomizer() { #ifdef __MINGW32__ BOOL r = ::CryptAcquireContext( &provider_, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT); assert(r); #endif } SimpleRandomizer::~SimpleRandomizer() { #ifdef __MINGW32__ CryptReleaseContext(provider_, 0); #endif } long int SimpleRandomizer::getRandomNumber(long int to) { assert(to > 0); return std::uniform_int_distribution(0, to - 1)(*this); } void SimpleRandomizer::getRandomBytes(unsigned char* buf, size_t len) { #ifdef __MINGW32__ BOOL r = CryptGenRandom(provider_, len, reinterpret_cast(buf)); assert(r); #elif defined(HAVE_GETRANDOM_INTERFACE) auto rv = getrandom_linux(buf, len); assert(rv >= 0 && (size_t)rv == len); #else // ! __MINGW32__ auto ubuf = reinterpret_cast(buf); size_t q = len / sizeof(result_type); auto gen = std::uniform_int_distribution(); for(; q > 0; --q, ++ubuf) { *ubuf = gen(dev_); } const size_t r = len % sizeof(result_type); auto last = gen(dev_); memcpy(ubuf, &last, r); #endif // ! __MINGW32__ } } // namespace aria2