From: Lennart Poettering Date: Wed, 11 Nov 2020 13:44:35 +0000 (+0100) Subject: random-util: add random_u64_range() that acquires a random number from a certain... X-Git-Tag: v248-rc1~137^2~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5464c961865e049279dc696a93fbaf08b8bc39ce;p=thirdparty%2Fsystemd.git random-util: add random_u64_range() that acquires a random number from a certain range, unbiased So far we have been quite sloppy with this and ignored modulus and range bias. Let's do something about, and add the option to do better. --- diff --git a/src/basic/random-util.c b/src/basic/random-util.c index c831f06dacf..eca81875717 100644 --- a/src/basic/random-util.c +++ b/src/basic/random-util.c @@ -494,3 +494,22 @@ int random_write_entropy(int fd, const void *seed, size_t size, bool credit) { return 1; } + +int random_u64_range(uint64_t m) { + uint64_t x, remainder; + + /* Generates a random number in the range 0…m-1, unbiased. (Java's algorithm) */ + + if (m == 0) /* Let's take m == 0 as special case to return an integer from the full range */ + return random_u64(); + if (m == 1) + return 0; + + remainder = UINT64_MAX % m; + + do { + x = random_u64(); + } while (x >= UINT64_MAX - remainder); + + return x % m; +} diff --git a/src/basic/random-util.h b/src/basic/random-util.h index f661fc093ae..1d5fb60fa24 100644 --- a/src/basic/random-util.h +++ b/src/basic/random-util.h @@ -40,3 +40,5 @@ int rdrand(unsigned long *ret); size_t random_pool_size(void); int random_write_entropy(int fd, const void *seed, size_t size, bool credit); + +int random_u64_range(uint64_t max);