exit (status);
}
+/* Single-word RNG built on top of ISAAC */
+struct irand_state
+{
+ uint32_t r[ISAAC_WORDS];
+ unsigned int numleft;
+ struct isaac_state *s;
+};
+
+static void
+irand_init (struct irand_state *r, struct isaac_state *s)
+{
+ r->numleft = 0;
+ r->s = s;
+}
+
+/*
+ * We take from the end of the block deliberately, so if we need
+ * only a small number of values, we choose the final ones which are
+ * marginally better mixed than the initial ones.
+ */
+static uint32_t
+irand32 (struct irand_state *r)
+{
+ if (!r->numleft)
+ {
+ isaac_refill (r->s, r->r);
+ r->numleft = ISAAC_WORDS;
+ }
+ return r->r[--r->numleft];
+}
+
+/*
+ * Return a uniformly distributed random number between 0 and n,
+ * inclusive. Thus, the result is modulo n+1.
+ *
+ * Theory of operation: as x steps through every possible 32-bit number,
+ * x % n takes each value at least 2^32 / n times (rounded down), but
+ * the values less than 2^32 % n are taken one additional time. Thus,
+ * x % n is not perfectly uniform. To fix this, the values of x less
+ * than 2^32 % n are disallowed, and if the RNG produces one, we ask
+ * for a new value.
+ */
+static uint32_t
+irand_mod (struct irand_state *r, uint32_t n)
+{
+ uint32_t x;
+ uint32_t lim;
+
+ if (!++n)
+ return irand32 (r);
+
+ lim = -n % n; /* == (2**32-n) % n == 2**32 % n */
+ do
+ {
+ x = irand32 (r);
+ }
+ while (x < lim);
+ return x % n;
+}
+
/*
* Fill a buffer with a fixed pattern.
*