From 67fb94dea61e74da032a8f0c51fbf216ec47dadb Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Wed, 11 Jan 2023 08:13:53 +0000 Subject: awk: further improvements to randomness POSIX requires that the awk srand() function uses the time of day to seed the PRNG. The obvious implementation used in BusyBox does exactly that, passing time(NULL) to srand(3). When processes are started within a few seconds of one another their seeds are very similar. Given the realtively poor quality of rand(3) in some C runtimes this results in random number sequences that are somewhat correlated. Improve matters by using an integer hash on the seed, as recommended here: https://nullprogram.com/blog/2019/04/30/#the-wrong-places Costs 48 bytes. (GitHub issue #279) --- editors/awk.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/editors/awk.c b/editors/awk.c index 342b93df9..cf9269c6f 100644 --- a/editors/awk.c +++ b/editors/awk.c @@ -2870,6 +2870,17 @@ static rstream *next_input_file(void) #undef files_happen } +#if ENABLE_PLATFORM_MINGW32 +static unsigned triple32(unsigned x) +{ + x ^= x >> 17; x *= 0xed5ad4bb; + x ^= x >> 11; x *= 0xac4c1b51; + x ^= x >> 15; x *= 0x31848bab; + x ^= x >> 14; + return x; +} +#endif + /* * Evaluate node - the heart of the program. Supplied with subtree * and "res" variable to assign the result to if we evaluate an expression. @@ -3329,7 +3340,11 @@ static var *evaluate(node *op, var *res) case F_sr: R_d = (double)seed; seed = op1 ? (unsigned)L_d : (unsigned)time(NULL); +#if ENABLE_PLATFORM_MINGW32 + srand(seed == 1 ? 1 : triple32(seed)); +#else srand(seed); +#endif break; case F_ti: /*systime*/ -- cgit v1.2.3-55-g6feb