summaryrefslogtreecommitdiff
path: root/src/SimpleRandomizer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/SimpleRandomizer.cc')
-rw-r--r--src/SimpleRandomizer.cc36
1 files changed, 22 insertions, 14 deletions
diff --git a/src/SimpleRandomizer.cc b/src/SimpleRandomizer.cc
index 9754d6cb..89e0ffd1 100644
--- a/src/SimpleRandomizer.cc
+++ b/src/SimpleRandomizer.cc
@@ -38,6 +38,7 @@
#include <unistd.h>
#include <cstdlib>
#include <cassert>
+#include <cstring>
#include "a2time.h"
@@ -56,7 +57,8 @@ const std::unique_ptr<SimpleRandomizer>& SimpleRandomizer::getInstance()
void SimpleRandomizer::init()
{
#ifndef __MINGW32__
- srandom(time(nullptr)^getpid());
+ // Just in case std::random_device() is fixed, add time and pid too.
+ eng_.seed(std::random_device()()^time(nullptr)^getpid());
#endif // !__MINGW32__
}
@@ -90,7 +92,7 @@ long int SimpleRandomizer::getRandomNumber()
}
return val;
#else // !__MINGW32__
- return random();
+ return eng_();
#endif // !__MINGW32__
}
@@ -99,15 +101,18 @@ long int SimpleRandomizer::getMaxRandomNumber()
#ifdef __MINGW32__
return INT32_MAX;
#else // !__MINGW32__
- // TODO Warning: The maximum value of random() in some sytems (e.g.,
- // Solaris and openbsd) is (2**31)-1.
- return RAND_MAX;
+ return eng_.max();
#endif // !__MINGW32__
}
long int SimpleRandomizer::getRandomNumber(long int to)
{
+ assert(to > 0);
+#ifdef __MINGW32__
return getRandomNumber() % to;
+#else // !__MINGW32__
+ return std::uniform_int_distribution<long int>(0, to - 1)(eng_);
+#endif // !__MINGW32__
}
long int SimpleRandomizer::operator()(long int to)
@@ -122,16 +127,19 @@ void SimpleRandomizer::getRandomBytes(unsigned char *buf, size_t len)
throw std::bad_alloc();
}
#else
- while (len) {
- // If RAND_MAX is less than 2**16-1, we are in trouble.
- union {
- uint16_t r;
- uint8_t b[2];
- } r = { (uint16_t)(random() & 0xffffu) };
- for (auto i = 0; i < 2 && len; ++i, --len) {
- *buf++ = r.b[i];
- }
+ uint32_t val;
+ size_t q = len / sizeof(val);
+ size_t r = len % sizeof(val);
+ auto gen = std::bind(std::uniform_int_distribution<uint32_t>
+ (0, std::numeric_limits<uint32_t>::max()),
+ eng_);
+ for(; q > 0; --q) {
+ val = gen();
+ memcpy(buf, &val, sizeof(val));
+ buf += sizeof(val);
}
+ val = gen();
+ memcpy(buf, &val, r);
#endif
}