Browse Source

std_utils: further improve the random funcs, hopefully.

LIB-19
heck 4 years ago
parent
commit
8a6aba672d
  1. 31
      src/std_utils.cc
  2. 5
      src/std_utils.hh
  3. 8
      src/std_utils.hxx

31
src/std_utils.cc

@ -13,6 +13,8 @@
#include <random> #include <random>
#include <cstring> #include <cstring>
#include <iomanip> #include <iomanip>
#include <pEp/pEpLog.hh>
#ifndef WIN32 #ifndef WIN32
#include <dirent.h> #include <dirent.h>
#include <sys/stat.h> #include <sys/stat.h>
@ -342,19 +344,32 @@ namespace pEp {
std::this_thread::sleep_for(timespan); std::this_thread::sleep_for(timespan);
} }
int fastrand(int max) // Random --------------------------------------------------------------------------------
unsigned g_seed = gen_seed();
std::mt19937 gen{ g_seed };
uint gen_seed()
{
uint ret{};
if (std::random_device{}.entropy() > 0) {
ret = std::random_device{}();
} else {
pEpLog("gen_seed(): No real random device present, falling back to epoch-time");
ret = std::chrono::system_clock::now().time_since_epoch().count();
}
assert(ret != 0);
return ret;
}
unsigned int random_fast(int max)
{ {
static int g_seed = static_cast<int>(
std::chrono::system_clock::now().time_since_epoch().count());
g_seed = (214013 * g_seed + 2531011); g_seed = (214013 * g_seed + 2531011);
return ((g_seed >> 16) & 0x7FFF) % max + 1; return ((g_seed >> 16) & 0x7FFF) % max + 1;
} }
unsigned char random_char(unsigned char min, unsigned char max) unsigned char random_char(unsigned char min, unsigned char max)
{ {
static unsigned seed1 = std::chrono::system_clock::now().time_since_epoch().count(); std::uniform_int_distribution<unsigned char> dis(min, max);
static std::mt19937 gen{ seed1 };
static std::uniform_int_distribution<unsigned char> dis(min, max);
return dis(gen); return dis(gen);
} }
@ -369,10 +384,10 @@ namespace pEp {
std::string random_string_fast(unsigned char min, unsigned char max, int len) std::string random_string_fast(unsigned char min, unsigned char max, int len)
{ {
int range = std::max(max - min, 1); int range = std::max(max - min, 0);
std::stringstream ret; std::stringstream ret;
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
ret << (fastrand(range) + min); ret << static_cast<unsigned char>(random_fast(range) + min);
} }
return ret.str(); return ret.str();
} }

5
src/std_utils.hh

@ -93,7 +93,10 @@ namespace pEp {
void sleep_millis(int milis); void sleep_millis(int milis);
// Random // Random
int fastrand(int max); // Attention: calling gen_seed() often will exhaust your entropy pool.
// If no random devices present, will return epoch-time.
unsigned int gen_seed();
unsigned int random_fast(int max);
unsigned char random_char(unsigned char min, unsigned char max); unsigned char random_char(unsigned char min, unsigned char max);
std::string random_string(unsigned char min, unsigned char max, int len); std::string random_string(unsigned char min, unsigned char max, int len);
std::string random_string_fast(unsigned char min, unsigned char max, int len); std::string random_string_fast(unsigned char min, unsigned char max, int len);

8
src/std_utils.hxx

@ -61,10 +61,10 @@ namespace pEp {
return ret; return ret;
} }
template<class T> template<class T = unsigned char>
T hex2bin(const std::string &hex_str) std::vector<T> hex2bin(const std::string &hex_str)
{ {
T ret{}; std::vector<T> ret{};
if ((hex_str.size() % 2) != 0) { if ((hex_str.size() % 2) != 0) {
throw std::runtime_error("hex2bin: Invalid hex string: must be even length"); throw std::runtime_error("hex2bin: Invalid hex string: must be even length");
} }
@ -79,7 +79,7 @@ namespace pEp {
if (conv_ss.fail()) { if (conv_ss.fail()) {
throw std::runtime_error("hex2bin: invalid hex string" + hex_str); throw std::runtime_error("hex2bin: invalid hex string" + hex_str);
} }
ret.push_back(static_cast<typename T::value_type>(val_int)); ret.push_back(static_cast<T>(val_int));
} }
return ret; return ret;

Loading…
Cancel
Save