summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortholo <>1996-03-30 10:01:47 +0000
committertholo <>1996-03-30 10:01:47 +0000
commit83fa873dce1a7d0a9a23de76faf3817f44278e9b (patch)
tree0ff35e4c3fc6960d623f7f3d7b125fafb2a9a51b
parent459b9ce58e48cda3e0c36646c65c2c1ec402dd50 (diff)
downloadopenbsd-83fa873dce1a7d0a9a23de76faf3817f44278e9b.tar.gz
openbsd-83fa873dce1a7d0a9a23de76faf3817f44278e9b.tar.bz2
openbsd-83fa873dce1a7d0a9a23de76faf3817f44278e9b.zip
Substantially improve random number generation by using the largest prime
that fits inside 32 bits as the denominator; take care not to overflow. Regenerate initial seed after replacing the generator
-rw-r--r--src/lib/libc/stdlib/random.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/src/lib/libc/stdlib/random.c b/src/lib/libc/stdlib/random.c
index 469b6d976a..9b1fe3c738 100644
--- a/src/lib/libc/stdlib/random.c
+++ b/src/lib/libc/stdlib/random.c
@@ -33,7 +33,7 @@
33 33
34#if defined(LIBC_SCCS) && !defined(lint) 34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)random.c 5.9 (Berkeley) 2/23/91";*/ 35/*static char *sccsid = "from: @(#)random.c 5.9 (Berkeley) 2/23/91";*/
36static char *rcsid = "$Id: random.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $"; 36static char *rcsid = "$Id: random.c,v 1.2 1996/03/30 10:01:47 tholo Exp $";
37#endif /* LIBC_SCCS and not lint */ 37#endif /* LIBC_SCCS and not lint */
38 38
39#include <stdio.h> 39#include <stdio.h>
@@ -136,12 +136,12 @@ static int seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
136 136
137static long randtbl[DEG_3 + 1] = { 137static long randtbl[DEG_3 + 1] = {
138 TYPE_3, 138 TYPE_3,
139 0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342, 0xde3b81e0, 0xdf0a6fb5, 139 0x991539b1, 0x16a5bce3, 0x6774a4cd, 0x3e01511e, 0x4e508aaa, 0x61048c05,
140 0xf103bc02, 0x48f340fb, 0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd, 140 0xf5500617, 0x846b7115, 0x6a19892c, 0x896a97af, 0xdb48f936, 0x14898454,
141 0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86, 0xda672e2a, 0x1588ca88, 141 0x37ffd106, 0xb58bff9c, 0x59e17104, 0xcf918a49, 0x09378c83, 0x52c7a471,
142 0xe369735d, 0x904f35f7, 0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc, 142 0x8d293ea9, 0x1f4fc301, 0xc3db71be, 0x39b44e1c, 0xf8a44ef9, 0x4c8b80b1,
143 0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b, 0xf5ad9d0e, 0x8999220b, 143 0x19edc328, 0x87bf4bdd, 0xc9b240e5, 0xe9ee4b1b, 0x4382aee7, 0x535b6b41,
144 0x27fb47b9, 144 0xf3bec5da,
145}; 145};
146 146
147/* 147/*
@@ -193,15 +193,27 @@ void
193srandom(x) 193srandom(x)
194 u_int x; 194 u_int x;
195{ 195{
196 register long int test;
196 register int i, j; 197 register int i, j;
198 ldiv_t val;
197 199
198 if (rand_type == TYPE_0) 200 if (rand_type == TYPE_0)
199 state[0] = x; 201 state[0] = x;
200 else { 202 else {
201 j = 1; 203 j = 1;
202 state[0] = x; 204 state[0] = x;
203 for (i = 1; i < rand_deg; i++) 205 for (i = 1; i < rand_deg; i++) {
204 state[i] = 1103515245 * state[i - 1] + 12345; 206 /*
207 * Implement the following, without overflowing 31 bits:
208 *
209 * state[i] = (16807 * state[i - 1]) % 2147483647;
210 *
211 * 2^31-1 (prime) = 2147483647 = 127773*16807+2836
212 */
213 val = ldiv(state[i-1], 127773);
214 test = 16807 * val.rem - 2836 * val.quot;
215 state[i] = test + (test < 0 ? 2147483647 : 0);
216 }
205 fptr = &state[rand_sep]; 217 fptr = &state[rand_sep];
206 rptr = &state[0]; 218 rptr = &state[0];
207 for (i = 0; i < 10 * rand_deg; i++) 219 for (i = 0; i < 10 * rand_deg; i++)