17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-11-07 19:14:46 +01:00

Improve random engine entropy and clean up random engine initialization

This commit is contained in:
2026-09-14 19:26:24 +02:00
parent 1c2f397fc5
commit 788135cc2d
4 changed files with 23 additions and 13 deletions

View File

@@ -321,7 +321,7 @@ int eu07_application::init(int Argc, char *Argv[])
} }
if (!Global.random_seed) if (!Global.random_seed)
Global.random_seed = clock_seed(); Global.random_seed = true_random_seed();
Global.random_engine.seed(Global.random_seed); Global.random_engine.seed(Global.random_seed);
// configure the OS console according to Globals.ShowSystemConsole. // configure the OS console according to Globals.ShowSystemConsole.
@@ -1432,7 +1432,7 @@ int eu07_application::init_data()
int eu07_application::init_modes() int eu07_application::init_modes()
{ {
Global.local_random_engine.seed(clock_seed()); Global.local_random_engine.seed(true_random_seed());
if ((!Global.network_servers.empty() || Global.network_client) && Global.SceneryFile.empty()) if ((!Global.network_servers.empty() || Global.network_client) && Global.SceneryFile.empty())
{ {

View File

@@ -138,10 +138,20 @@ int Random(int min, int max)
return dist(Global.random_engine); return dist(Global.random_engine);
} }
std::uint32_t clock_seed() std::uint64_t true_random_seed()
{ {
static std::atomic<std::uint32_t> nth{0}; try
return static_cast<std::uint32_t>(std::time({})) + nth.fetch_add(1, std::memory_order_relaxed); {
std::random_device rd;
if (rd.entropy() > 0.0)
{
std::uint32_t high = rd();
std::uint32_t low = rd();
return (high << 32) | low;
}
}
catch (...) {}
return static_cast<std::uint64_t>(std::chrono::high_resolution_clock::now().time_since_epoch().count());
} }
std::uint32_t seed_of(std::string const &Text) std::uint32_t seed_of(std::string const &Text)
@@ -161,12 +171,11 @@ std::uint32_t seed_of(std::string const &Text)
std::string generate_uuid_v4() std::string generate_uuid_v4()
{ {
static thread_local std::mt19937 generator{clock_seed()};
std::uniform_int_distribution<int> dist(0, 255); std::uniform_int_distribution<int> dist(0, 255);
std::array<uint8_t, 16> bytes; std::array<uint8_t, 16> bytes;
for (auto &b : bytes) for (auto &b : bytes)
b = static_cast<uint8_t>(dist(generator)); b = static_cast<uint8_t>(dist(Global.random_engine));
// UUID v4 (RFC 4122) // UUID v4 (RFC 4122)
bytes[6] = bytes[6] & 0x0F | 0x40; bytes[6] = bytes[6] & 0x0F | 0x40;

View File

@@ -63,9 +63,10 @@ inline long Round(double const f)
double Random(double a, double b); double Random(double a, double b);
int Random(int min, int max); int Random(int min, int max);
// Seed for the random engines: the clock, plus a counter so two engines seeded in /// @author lxvia
// the same second do not come out the same. /// @brief Returns a random seed from the system's entropy source, if available. Otherwise, falls back to a clock-based seed.
std::uint32_t clock_seed(); /// @return A random seed as 64 bit unsigned integer
std::uint64_t true_random_seed();
// The seed a word stands for. A number is taken as it is written; anything else is // The seed a word stands for. A number is taken as it is written; anything else is
// hashed the way Java's String.hashCode does it, so the same word gives the same // hashed the way Java's String.hashCode does it, so the same word gives the same

View File

@@ -7,6 +7,7 @@
#include <algorithm> #include <algorithm>
#include <cstdint> #include <cstdint>
#include "utilities/utilities.h" #include "utilities/utilities.h"
#include "utilities/Globals.h"
class UID { class UID {
public: public:
@@ -14,10 +15,9 @@ public:
static UID random() { static UID random() {
static thread_local std::mt19937_64 gen{clock_seed()};
UID u; UID u;
uint64_t a = gen(); uint64_t a = Global.random_engine();
uint64_t b = gen(); uint64_t b = Global.random_engine();
for (int i = 0; i < 8; ++i) u.bytes[i] = uint8_t(a >> (i * 8) & 0xFF); for (int i = 0; i < 8; ++i) u.bytes[i] = uint8_t(a >> (i * 8) & 0xFF);
for (int i = 0; i < 8; ++i) u.bytes[8 + i] = uint8_t(b >> (i * 8) & 0xFF); for (int i = 0; i < 8; ++i) u.bytes[8 + i] = uint8_t(b >> (i * 8) & 0xFF);