From: Pavel Charvat Date: Tue, 9 Jun 2020 16:51:46 +0000 (+0200) Subject: Random: fastrand_mem() is now deterministic. X-Git-Tag: v6.5.14~7 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=88e6eec58f7795be9ae91bdc22fda82b357bc00a;p=libucw.git Random: fastrand_mem() is now deterministic. --- diff --git a/ucw/random-fast.c b/ucw/random-fast.c index 5c8bfaab..672ccd88 100644 --- a/ucw/random-fast.c +++ b/ucw/random-fast.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -581,41 +582,24 @@ u64 fastrand_max_u64(struct fastrand *c, u64 bound) void fastrand_mem(struct fastrand *c, void *ptr, size_t size) { + // XXX: Could be optimized to aligned assignments instead of put_u32/64, but it + // would be quite complex to make it deterministic (for same seed and any @ptr) + // and large sizes are not used often anyway. FASTRAND_CHECK_SEED(c); byte *p = ptr; - if (size > 3) +#if FASTRAND_ONE_BITS < 64 + for (size_t n = size >> 2; n--; p += 4) + put_u32(p, fastrand_u32_helper(c)); + if (size &= 3) { - if ((intptr_t)p & 3) - { - u32 x = fastrand_u32_helper(c); - while ((intptr_t)p & 3) - { - *p++ = x; - x >>= 8; - size--; - } - } -#if FASTRAND_ONE_BITS == 64 - for (size_t n = size >> 3; n--; ) - { - u64 x = fastrand_one(c); - ((u32 *)p)[0] = x; - ((u32 *)p)[1] = x >> 32; - p += 8; - } - if (size & 4) + u32 x = fastrand_u32_helper(c); #else - for (size_t n = size >> 2; n--; ) -#endif - { - *(u32 *)p = fastrand_u32_helper(c); - p += 4; - } - size &= 3; - } - if (size) + for (size_t n = size >> 3; n--; p += 8) + put_u64(p, fastrand_one(c)); + if (size &= 7) { - u32 x = fastrand_u32_helper(c); + u64 x = fastrand_one(c); +#endif while (size--) { *p++ = x; diff --git a/ucw/random.h b/ucw/random.h index 93c6b28f..703b1b09 100644 --- a/ucw/random.h +++ b/ucw/random.h @@ -76,7 +76,7 @@ u32 fastrand_u32(struct fastrand *c); /** Uniformly generate 64 random bits. **/ u64 fastrand_u64(struct fastrand *c); -/** Uniformly generate [0..64] random bits. **/ +/** Uniformly generate [0, 64] random bits. **/ u64 fastrand_bits_u64(struct fastrand *c, uint bits); /** Uniformly generate [0, 8*sizeof(uint)] random bits. **/