From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> The current virRandomBits() API is only usable if the caller wants a random number in the range [0, (n-1)] where n is a power of two. This adds a virRandom() API which works for upper limits which are not a power of two. It works by using virRandomBits() to generate a number to the next nearest power of 2 limit, and then scales it down. Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx> --- src/libvirt_private.syms | 1 + src/util/virrandom.c | 34 ++++++++++++++++++++++++++++++++++ src/util/virrandom.h | 1 + 3 files changed, 36 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index c023dbf..d406785 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1640,6 +1640,7 @@ virPidFileDeletePath; # virrandom.h +virRandom; virRandomBits; virRandomGenerateWWN; diff --git a/src/util/virrandom.c b/src/util/virrandom.c index 50bed46..260cc82 100644 --- a/src/util/virrandom.c +++ b/src/util/virrandom.c @@ -108,6 +108,40 @@ uint64_t virRandomBits(int nbits) return ret; } + +/** + * virRandom: + * @max: Upper bound on random number (not inclusive) + * + * Generate an evenly distributed random number between [0,max-1] + * If @max is a power of 2, then use virRandomBits instead + * + * Return: a random number with @nbits entropy + */ +uint64_t virRandom(unsigned long long max) +{ + int bits = 0; + unsigned long long tmp = max - 1; + uint64_t ret; + + while (tmp) { + tmp >>= 1; + bits++; + } + + ret = virRandomBits(bits); + + if ((1 << bits) != max) { + double d = ret; + d *= max; + d /= (1 << bits); + ret = (uint64_t)d; + } + + return ret; +} + + #define QUMRANET_OUI "001a4a" #define VMWARE_OUI "000569" #define MICROSOFT_OUI "0050f2" diff --git a/src/util/virrandom.h b/src/util/virrandom.h index 29a055d..16d9fc7 100644 --- a/src/util/virrandom.h +++ b/src/util/virrandom.h @@ -25,6 +25,7 @@ # include "internal.h" uint64_t virRandomBits(int nbits); +uint64_t virRandom(unsigned long long max); int virRandomGenerateWWN(char **wwn, const char *virt_type); #endif /* __VIR_RANDOM_H__ */ -- 1.7.11.2 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list