From 25d1e5341b34db0855c2dd2823a2f2af94093803 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Mon, 4 Aug 2014 14:04:08 -0400 Subject: Use a repeatable cross-platform PRNG. --- util.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'util.c') diff --git a/util.c b/util.c index 3c61cde..a2573a4 100644 --- a/util.c +++ b/util.c @@ -31,3 +31,36 @@ xrealloc(void *ptr, size_t size) } return ret; } + +// Based on sample rand() implementation from POSIX.1-2001 + +static unsigned long xrand_next = 0; + +void xsrand(unsigned int seed) { + xrand_next = seed; +} + +static unsigned int xrand_simple(void) { + xrand_next = xrand_next*1103515245 + 12345; + return (unsigned int)(xrand_next/65536)%32768; +} + +static unsigned int xrand_full(void) { + unsigned int low = xrand_simple(); + unsigned int high = xrand_simple(); + return low | (high << 15); +} + +#define XRAND_RANGE 1073741824U + +unsigned int +xrand(unsigned int range) +{ + // Compensate for bias if XRAND_RANGE isn't a multiple of range + unsigned int limit = XRAND_RANGE - XRAND_RANGE%range; + unsigned int res; + do { + res = xrand_full(); + } while (res >= limit); + return res%range; +} -- cgit v1.2.3