]> mj.ucw.cz Git - libucw.git/commitdiff
Added random_u64() and random_max_u64().
authorMartin Mares <mj@ucw.cz>
Fri, 15 Sep 2006 19:00:12 +0000 (21:00 +0200)
committerMartin Mares <mj@ucw.cz>
Fri, 15 Sep 2006 19:00:12 +0000 (21:00 +0200)
lib/lib.h
lib/random.c

index b20ba7e9b284a0aa9d0815a66af71caf803fb87b..5ab134f0ccbe2d0f3b9756f18942bef6c5413983 100644 (file)
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -208,7 +208,9 @@ int rx_subst(regex *r, byte *by, byte *src, byte *dest, uns destlen);
 
 /* random.c */
 
-uns random_max(uns);
+uns random_max(uns max);
+u64 random_u64(void);
+u64 random_max_u64(u64 max);
 
 /* mmap.c */
 
index 7f88489d7cd00cf1c0d1721c6cfa38d2ce601244..87f7f544b5e95f47918e486610679c91a3a58c22 100644 (file)
@@ -1,7 +1,7 @@
 /*
- *     UCW Library -- Unbiased Range Correction for random()
+ *     UCW Library -- Unbiased Random Numbers
  *
- *     (c) 1998 Martin Mares <mj@ucw.cz>
+ *     (c) 1998--2006 Martin Mares <mj@ucw.cz>
  *
  *     This software may be freely distributed and used according to the terms
  *     of the GNU Lesser General Public License.
@@ -11,6 +11,9 @@
 
 #include <stdlib.h>
 
+/* We expect the random generator in libc to give at least 30 bits of randomness */
+COMPILE_ASSERT(RAND_MAX_RANGE_TEST, RAND_MAX >= (1 << 30)-1);
+
 uns
 random_max(uns max)
 {
@@ -22,3 +25,27 @@ random_max(uns max)
   while (r >= l);
   return r % max;
 }
+
+u64
+random_u64(void)
+{
+  return
+    ((u64)(random() & 0xffff) << 48) |
+    ((u64)(random() & 0xffffff) << 24) |
+    (random() & 0xffffff);
+}
+
+u64
+random_max_u64(u64 max)
+{
+  if (max < (1 << 30))
+    return random_max(max);
+
+  u64 r, l, m;
+  m = 0xffffffffffffffff;
+  l = m - (m % max);
+  do
+    r = random_u64();
+  while (r >= l);
+  return r % max;
+}