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.c134
1 files changed, 83 insertions, 51 deletions
diff --git a/src/lib/libc/stdlib/random.c b/src/lib/libc/stdlib/random.c
index 469b6d976a..9c5b9d0f3f 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.17 2012/06/01 01:01:57 guenther 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,29 @@ 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; 199 /* A seed of 0 would result in state[] always being zero. */
202 state[0] = x; 200 state[0] = x ? x : 1;
203 for (i = 1; i < rand_deg; i++) 201 for (i = 1; i < rand_deg; i++) {
204 state[i] = 1103515245 * state[i - 1] + 12345; 202 /*
203 * Implement the following, without overflowing 31 bits:
204 *
205 * state[i] = (16807 * state[i - 1]) % 2147483647;
206 *
207 * 2^31-1 (prime) = 2147483647 = 127773*16807+2836
208 */
209 val = div(state[i-1], 127773);
210 test = 16807 * val.rem - 2836 * val.quot;
211 state[i] = test + (test < 0 ? 2147483647 : 0);
212 }
205 fptr = &state[rand_sep]; 213 fptr = &state[rand_sep];
206 rptr = &state[0]; 214 rptr = &state[0];
207 for (i = 0; i < 10 * rand_deg; i++) 215 for (i = 0; i < 10 * rand_deg; i++)
@@ -210,6 +218,38 @@ srandom(x)
210} 218}
211 219
212/* 220/*
221 * srandomdev:
222 *
223 * Many programs choose the seed value in a totally predictable manner.
224 * This often causes problems. We seed the generator using random
225 * data from the kernel.
226 * Note that this particular seeding procedure can generate states
227 * which are impossible to reproduce by calling srandom() with any
228 * value, since the succeeding terms in the state buffer are no longer
229 * derived from the LC algorithm applied to a fixed seed.
230 */
231void
232srandomdev(void)
233{
234 int mib[2];
235 size_t len;
236
237 if (rand_type == TYPE_0)
238 len = sizeof(state[0]);
239 else
240 len = rand_deg * sizeof(state[0]);
241
242 mib[0] = CTL_KERN;
243 mib[1] = KERN_ARND;
244 sysctl(mib, 2, state, &len, NULL, 0);
245
246 if (rand_type != TYPE_0) {
247 fptr = &state[rand_sep];
248 rptr = &state[0];
249 }
250}
251
252/*
213 * initstate: 253 * initstate:
214 * 254 *
215 * Initialize the state information in the given array of n bytes for future 255 * Initialize the state information in the given array of n bytes for future
@@ -229,22 +269,16 @@ srandom(x)
229 * Returns a pointer to the old state. 269 * Returns a pointer to the old state.
230 */ 270 */
231char * 271char *
232initstate(seed, arg_state, n) 272initstate(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{ 273{
237 register char *ostate = (char *)(&state[-1]); 274 char *ostate = (char *)(&state[-1]);
238 275
239 if (rand_type == TYPE_0) 276 if (rand_type == TYPE_0)
240 state[-1] = rand_type; 277 state[-1] = rand_type;
241 else 278 else
242 state[-1] = MAX_TYPES * (rptr - state) + rand_type; 279 state[-1] = MAX_TYPES * (rptr - state) + rand_type;
243 if (n < BREAK_0) { 280 if (n < BREAK_0)
244 (void)fprintf(stderr, 281 return(NULL);
245 "random: not enough state (%d bytes); ignored.\n", n);
246 return(0);
247 }
248 if (n < BREAK_1) { 282 if (n < BREAK_1) {
249 rand_type = TYPE_0; 283 rand_type = TYPE_0;
250 rand_deg = DEG_0; 284 rand_deg = DEG_0;
@@ -266,7 +300,7 @@ initstate(seed, arg_state, n)
266 rand_deg = DEG_4; 300 rand_deg = DEG_4;
267 rand_sep = SEP_4; 301 rand_sep = SEP_4;
268 } 302 }
269 state = &(((long *)arg_state)[1]); /* first location */ 303 state = &(((int32_t *)arg_state)[1]); /* first location */
270 end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */ 304 end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */
271 srandom(seed); 305 srandom(seed);
272 if (rand_type == TYPE_0) 306 if (rand_type == TYPE_0)
@@ -292,12 +326,11 @@ initstate(seed, arg_state, n)
292 * Returns a pointer to the old state information. 326 * Returns a pointer to the old state information.
293 */ 327 */
294char * 328char *
295setstate(arg_state) 329setstate(char *arg_state)
296 char *arg_state;
297{ 330{
298 register long *new_state = (long *)arg_state; 331 int32_t *new_state = (int32_t *)arg_state;
299 register int type = new_state[0] % MAX_TYPES; 332 int32_t type = new_state[0] % MAX_TYPES;
300 register int rear = new_state[0] / MAX_TYPES; 333 int32_t rear = new_state[0] / MAX_TYPES;
301 char *ostate = (char *)(&state[-1]); 334 char *ostate = (char *)(&state[-1]);
302 335
303 if (rand_type == TYPE_0) 336 if (rand_type == TYPE_0)
@@ -315,8 +348,7 @@ setstate(arg_state)
315 rand_sep = seps[type]; 348 rand_sep = seps[type];
316 break; 349 break;
317 default: 350 default:
318 (void)fprintf(stderr, 351 return(NULL);
319 "random: state info corrupted; not changed.\n");
320 } 352 }
321 state = &new_state[1]; 353 state = &new_state[1];
322 if (rand_type != TYPE_0) { 354 if (rand_type != TYPE_0) {
@@ -345,9 +377,9 @@ setstate(arg_state)
345 * Returns a 31-bit random number. 377 * Returns a 31-bit random number.
346 */ 378 */
347long 379long
348random() 380random(void)
349{ 381{
350 long i; 382 int32_t i;
351 383
352 if (rand_type == TYPE_0) 384 if (rand_type == TYPE_0)
353 i = state[0] = (state[0] * 1103515245 + 12345) & 0x7fffffff; 385 i = state[0] = (state[0] * 1103515245 + 12345) & 0x7fffffff;
@@ -360,5 +392,5 @@ random()
360 } else if (++rptr >= end_ptr) 392 } else if (++rptr >= end_ptr)
361 rptr = state; 393 rptr = state;
362 } 394 }
363 return(i); 395 return((long)i);
364} 396}