From 8a6aba672dab419440bc603ecf21514ac0410210 Mon Sep 17 00:00:00 2001 From: heck Date: Sun, 17 Oct 2021 23:12:11 +0200 Subject: [PATCH] std_utils: further improve the random funcs, hopefully. --- src/std_utils.cc | 31 +++++++++++++++++++++++-------- src/std_utils.hh | 5 ++++- src/std_utils.hxx | 8 ++++---- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/std_utils.cc b/src/std_utils.cc index 50004f9..462690c 100644 --- a/src/std_utils.cc +++ b/src/std_utils.cc @@ -13,6 +13,8 @@ #include #include #include +#include + #ifndef WIN32 #include #include @@ -342,19 +344,32 @@ namespace pEp { 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( - std::chrono::system_clock::now().time_since_epoch().count()); g_seed = (214013 * g_seed + 2531011); return ((g_seed >> 16) & 0x7FFF) % max + 1; } unsigned char random_char(unsigned char min, unsigned char max) { - static unsigned seed1 = std::chrono::system_clock::now().time_since_epoch().count(); - static std::mt19937 gen{ seed1 }; - static std::uniform_int_distribution dis(min, max); + std::uniform_int_distribution dis(min, max); return dis(gen); } @@ -369,10 +384,10 @@ namespace pEp { 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; for (int i = 0; i < len; i++) { - ret << (fastrand(range) + min); + ret << static_cast(random_fast(range) + min); } return ret.str(); } diff --git a/src/std_utils.hh b/src/std_utils.hh index dafb5f7..7275c93 100644 --- a/src/std_utils.hh +++ b/src/std_utils.hh @@ -93,7 +93,10 @@ namespace pEp { void sleep_millis(int milis); // 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); 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); diff --git a/src/std_utils.hxx b/src/std_utils.hxx index 199748e..fb21076 100644 --- a/src/std_utils.hxx +++ b/src/std_utils.hxx @@ -61,10 +61,10 @@ namespace pEp { return ret; } - template - T hex2bin(const std::string &hex_str) + template + std::vector hex2bin(const std::string &hex_str) { - T ret{}; + std::vector ret{}; if ((hex_str.size() % 2) != 0) { throw std::runtime_error("hex2bin: Invalid hex string: must be even length"); } @@ -79,7 +79,7 @@ namespace pEp { if (conv_ss.fail()) { throw std::runtime_error("hex2bin: invalid hex string" + hex_str); } - ret.push_back(static_cast(val_int)); + ret.push_back(static_cast(val_int)); } return ret;