summaryrefslogtreecommitdiff
path: root/src/lib/libc/stdlib/random.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libc/stdlib/random.c')
-rw-r--r--src/lib/libc/stdlib/random.c131
1 files changed, 81 insertions, 50 deletions
diff --git a/src/lib/libc/stdlib/random.c b/src/lib/libc/stdlib/random.c
index 469b6d976a..48e892042b 100644
--- a/src/lib/libc/stdlib/random.c
+++ b/src/lib/libc/stdlib/random.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: random.c,v 1.15 2005/11/30 07:51:02 otto Exp $ */
1/* 2/*
2 * Copyright (c) 1983 Regents of the University of California. 3 * Copyright (c) 1983 Regents of the University of California.
3 * All rights reserved. 4 * All rights reserved.
@@ -10,11 +11,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 14 * 3. Neither the name of the University nor the names of its contributors
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software 15 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 16 * without specific prior written permission.
20 * 17 *
@@ -31,13 +28,13 @@
31 * SUCH DAMAGE. 28 * SUCH DAMAGE.
32 */ 29 */
33 30
34#if defined(LIBC_SCCS) && !defined(lint) 31#include <sys/param.h>
35/*static char *sccsid = "from: @(#)random.c 5.9 (Berkeley) 2/23/91";*/ 32#include <sys/sysctl.h>
36static char *rcsid = "$Id: random.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $"; 33#include <sys/time.h>
37#endif /* LIBC_SCCS and not lint */ 34#include <fcntl.h>
38
39#include <stdio.h> 35#include <stdio.h>
40#include <stdlib.h> 36#include <stdlib.h>
37#include <unistd.h>
41 38
42/* 39/*
43 * random.c: 40 * random.c:
@@ -55,10 +52,10 @@ static char *rcsid = "$Id: random.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $"
55 * congruential generator. If the amount of state information is less than 52 * congruential generator. If the amount of state information is less than
56 * 32 bytes, a simple linear congruential R.N.G. is used. 53 * 32 bytes, a simple linear congruential R.N.G. is used.
57 * 54 *
58 * Internally, the state information is treated as an array of longs; the 55 * Internally, the state information is treated as an array of int32_t; the
59 * zeroeth element of the array is the type of R.N.G. being used (small 56 * zeroeth element of the array is the type of R.N.G. being used (small
60 * integer); the remainder of the array is the state information for the 57 * integer); the remainder of the array is the state information for the
61 * R.N.G. Thus, 32 bytes of state information will give 7 longs worth of 58 * R.N.G. Thus, 32 bytes of state information will give 7 int32_ts worth of
62 * state information, which will allow a degree seven polynomial. (Note: 59 * state information, which will allow a degree seven polynomial. (Note:
63 * the zeroeth word of state information also has some other information 60 * the zeroeth word of state information also has some other information
64 * stored in it -- see setstate() for details). 61 * stored in it -- see setstate() for details).
@@ -134,14 +131,14 @@ static int seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
134 * MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3. 131 * MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3.
135 */ 132 */
136 133
137static long randtbl[DEG_3 + 1] = { 134static int32_t randtbl[DEG_3 + 1] = {
138 TYPE_3, 135 TYPE_3,
139 0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342, 0xde3b81e0, 0xdf0a6fb5, 136 0x991539b1, 0x16a5bce3, 0x6774a4cd, 0x3e01511e, 0x4e508aaa, 0x61048c05,
140 0xf103bc02, 0x48f340fb, 0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd, 137 0xf5500617, 0x846b7115, 0x6a19892c, 0x896a97af, 0xdb48f936, 0x14898454,
141 0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86, 0xda672e2a, 0x1588ca88, 138 0x37ffd106, 0xb58bff9c, 0x59e17104, 0xcf918a49, 0x09378c83, 0x52c7a471,
142 0xe369735d, 0x904f35f7, 0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc, 139 0x8d293ea9, 0x1f4fc301, 0xc3db71be, 0x39b44e1c, 0xf8a44ef9, 0x4c8b80b1,
143 0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b, 0xf5ad9d0e, 0x8999220b, 140 0x19edc328, 0x87bf4bdd, 0xc9b240e5, 0xe9ee4b1b, 0x4382aee7, 0x535b6b41,
144 0x27fb47b9, 141 0xf3bec5da,
145}; 142};
146 143
147/* 144/*
@@ -158,8 +155,8 @@ static long randtbl[DEG_3 + 1] = {
158 * in the initialization of randtbl) because the state table pointer is set 155 * in the initialization of randtbl) because the state table pointer is set
159 * to point to randtbl[1] (as explained below). 156 * to point to randtbl[1] (as explained below).
160 */ 157 */
161static long *fptr = &randtbl[SEP_3 + 1]; 158static int32_t *fptr = &randtbl[SEP_3 + 1];
162static long *rptr = &randtbl[1]; 159static int32_t *rptr = &randtbl[1];
163 160
164/* 161/*
165 * The following things are the pointer to the state information table, the 162 * The following things are the pointer to the state information table, the
@@ -171,11 +168,11 @@ static long *rptr = &randtbl[1];
171 * this is more efficient than indexing every time to find the address of 168 * this is more efficient than indexing every time to find the address of
172 * the last element to see if the front and rear pointers have wrapped. 169 * the last element to see if the front and rear pointers have wrapped.
173 */ 170 */
174static long *state = &randtbl[1]; 171static int32_t *state = &randtbl[1];
172static int32_t *end_ptr = &randtbl[DEG_3 + 1];
175static int rand_type = TYPE_3; 173static int rand_type = TYPE_3;
176static int rand_deg = DEG_3; 174static int rand_deg = DEG_3;
177static int rand_sep = SEP_3; 175static int rand_sep = SEP_3;
178static long *end_ptr = &randtbl[DEG_3 + 1];
179 176
180/* 177/*
181 * srandom: 178 * srandom:
@@ -190,18 +187,28 @@ static long *end_ptr = &randtbl[DEG_3 + 1];
190 * for default usage relies on values produced by this routine. 187 * for default usage relies on values produced by this routine.
191 */ 188 */
192void 189void
193srandom(x) 190srandom(unsigned int x)
194 u_int x;
195{ 191{
196 register int i, j; 192 int i;
193 int32_t test;
194 div_t val;
197 195
198 if (rand_type == TYPE_0) 196 if (rand_type == TYPE_0)
199 state[0] = x; 197 state[0] = x;
200 else { 198 else {
201 j = 1;
202 state[0] = x; 199 state[0] = x;
203 for (i = 1; i < rand_deg; i++) 200 for (i = 1; i < rand_deg; i++) {
204 state[i] = 1103515245 * state[i - 1] + 12345; 201 /*
202 * Implement the following, without overflowing 31 bits:
203 *
204 * state[i] = (16807 * state[i - 1]) % 2147483647;
205 *
206 * 2^31-1 (prime) = 2147483647 = 127773*16807+2836
207 */
208 val = div(state[i-1], 127773);
209 test = 16807 * val.rem - 2836 * val.quot;
210 state[i] = test + (test < 0 ? 2147483647 : 0);
211 }
205 fptr = &state[rand_sep]; 212 fptr = &state[rand_sep];
206 rptr = &state[0]; 213 rptr = &state[0];
207 for (i = 0; i < 10 * rand_deg; i++) 214 for (i = 0; i < 10 * rand_deg; i++)
@@ -210,6 +217,38 @@ srandom(x)
210} 217}
211 218
212/* 219/*
220 * srandomdev:
221 *
222 * Many programs choose the seed value in a totally predictable manner.
223 * This often causes problems. We seed the generator using random
224 * data from the kernel.
225 * Note that this particular seeding procedure can generate states
226 * which are impossible to reproduce by calling srandom() with any
227 * value, since the succeeding terms in the state buffer are no longer
228 * derived from the LC algorithm applied to a fixed seed.
229 */
230void
231srandomdev(void)
232{
233 int mib[2];
234 size_t len;
235
236 if (rand_type == TYPE_0)
237 len = sizeof(state[0]);
238 else
239 len = rand_deg * sizeof(state[0]);
240
241 mib[0] = CTL_KERN;
242 mib[1] = KERN_ARND;
243 sysctl(mib, 2, state, &len, NULL, 0);
244
245 if (rand_type != TYPE_0) {
246 fptr = &state[rand_sep];
247 rptr = &state[0];
248 }
249}
250
251/*
213 * initstate: 252 * initstate:
214 * 253 *
215 * Initialize the state information in the given array of n bytes for future 254 * Initialize the state information in the given array of n bytes for future
@@ -229,22 +268,16 @@ srandom(x)
229 * Returns a pointer to the old state. 268 * Returns a pointer to the old state.
230 */ 269 */
231char * 270char *
232initstate(seed, arg_state, n) 271initstate(u_int seed, char *arg_state, size_t n)
233 u_int seed; /* seed for R.N.G. */
234 char *arg_state; /* pointer to state array */
235 int n; /* # bytes of state info */
236{ 272{
237 register char *ostate = (char *)(&state[-1]); 273 char *ostate = (char *)(&state[-1]);
238 274
239 if (rand_type == TYPE_0) 275 if (rand_type == TYPE_0)
240 state[-1] = rand_type; 276 state[-1] = rand_type;
241 else 277 else
242 state[-1] = MAX_TYPES * (rptr - state) + rand_type; 278 state[-1] = MAX_TYPES * (rptr - state) + rand_type;
243 if (n < BREAK_0) { 279 if (n < BREAK_0)
244 (void)fprintf(stderr, 280 return(NULL);
245 "random: not enough state (%d bytes); ignored.\n", n);
246 return(0);
247 }
248 if (n < BREAK_1) { 281 if (n < BREAK_1) {
249 rand_type = TYPE_0; 282 rand_type = TYPE_0;
250 rand_deg = DEG_0; 283 rand_deg = DEG_0;
@@ -266,7 +299,7 @@ initstate(seed, arg_state, n)
266 rand_deg = DEG_4; 299 rand_deg = DEG_4;
267 rand_sep = SEP_4; 300 rand_sep = SEP_4;
268 } 301 }
269 state = &(((long *)arg_state)[1]); /* first location */ 302 state = &(((int32_t *)arg_state)[1]); /* first location */
270 end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */ 303 end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */
271 srandom(seed); 304 srandom(seed);
272 if (rand_type == TYPE_0) 305 if (rand_type == TYPE_0)
@@ -292,12 +325,11 @@ initstate(seed, arg_state, n)
292 * Returns a pointer to the old state information. 325 * Returns a pointer to the old state information.
293 */ 326 */
294char * 327char *
295setstate(arg_state) 328setstate(const char *arg_state)
296 char *arg_state;
297{ 329{
298 register long *new_state = (long *)arg_state; 330 int32_t *new_state = (int32_t *)arg_state;
299 register int type = new_state[0] % MAX_TYPES; 331 int32_t type = new_state[0] % MAX_TYPES;
300 register int rear = new_state[0] / MAX_TYPES; 332 int32_t rear = new_state[0] / MAX_TYPES;
301 char *ostate = (char *)(&state[-1]); 333 char *ostate = (char *)(&state[-1]);
302 334
303 if (rand_type == TYPE_0) 335 if (rand_type == TYPE_0)
@@ -315,8 +347,7 @@ setstate(arg_state)
315 rand_sep = seps[type]; 347 rand_sep = seps[type];
316 break; 348 break;
317 default: 349 default:
318 (void)fprintf(stderr, 350 return(NULL);
319 "random: state info corrupted; not changed.\n");
320 } 351 }
321 state = &new_state[1]; 352 state = &new_state[1];
322 if (rand_type != TYPE_0) { 353 if (rand_type != TYPE_0) {
@@ -345,9 +376,9 @@ setstate(arg_state)
345 * Returns a 31-bit random number. 376 * Returns a 31-bit random number.
346 */ 377 */
347long 378long
348random() 379random(void)
349{ 380{
350 long i; 381 int32_t i;
351 382
352 if (rand_type == TYPE_0) 383 if (rand_type == TYPE_0)
353 i = state[0] = (state[0] * 1103515245 + 12345) & 0x7fffffff; 384 i = state[0] = (state[0] * 1103515245 + 12345) & 0x7fffffff;
@@ -360,5 +391,5 @@ random()
360 } else if (++rptr >= end_ptr) 391 } else if (++rptr >= end_ptr)
361 rptr = state; 392 rptr = state;
362 } 393 }
363 return(i); 394 return((long)i);
364} 395}