From f3522129a3a7e97020a4b71cec4581d2a3978a8c Mon Sep 17 00:00:00 2001 From: Imbus <> Date: Thu, 28 Aug 2025 14:44:44 +0200 Subject: [PATCH] "Hardening" the bad prand --- prand.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/prand.c b/prand.c index 9adf181..ba65868 100644 --- a/prand.c +++ b/prand.c @@ -2,14 +2,13 @@ #include #include #include +#include -#define BUILD_SEED \ +#define PRAND_BUILD_SEED \ ((uint64_t)(__TIME__[0]) * (uint64_t)(__TIME__[1]) * (uint64_t)(__TIME__[3]) * (uint64_t)(__TIME__[4]) * \ (uint64_t)(__TIME__[6]) * (uint64_t)(__TIME__[7])) -#define PRNG_SAVE_INTERVAL 50 // Save every 1000 calls to prand() - -static uint64_t seed = BUILD_SEED; +static uint64_t seed = PRAND_BUILD_SEED * 6364136223846793005ULL + 1; uint64_t prand() { seed = seed * 6364136223846793005ULL + 1; @@ -17,31 +16,44 @@ uint64_t prand() { } inline uint64_t prand_range(uint64_t min, uint64_t max) { - return min + (prand() % (max - min + 1)); + uint64_t range = max - min + 1; + uint64_t x; + uint64_t limit = UINT64_MAX - (UINT64_MAX % range); + + do { + x = prand(); + } while (x > limit); + + return min + (x % range); } void sprand(uint64_t s) { if (s) { - seed = s; + seed ^= (s * 0x9e3779b97f4a7c15ULL) + (seed << 6) + (seed >> 2); } else { - rand_reseed(); + seed ^= PRAND_BUILD_SEED; } } -void rand_reseed() { - seed = BUILD_SEED; -} +#undef PRAND_BUILD_SEED #define PRAND_MAIN #ifdef PRAND_MAIN int main() { // time(NULL) provides a somewhat unique seed at runtime sprand(time(NULL)); + sprand(getpid()); + sprand(0); uint64_t rn1 = prand(); uint64_t rn2 = prand(); printf("rn1 = %lu\n", rn1); printf("rn2 = %lu\n", rn2); + + for (int i = 0; i < 40; i++) { + uint64_t random = prand_range(0, 1000); + printf("random = %lu\n", random); + } } #endif