1 | /*-␊ |
2 | * Copyright (c) 1990, 1993␊ |
3 | *␉The Regents of the University of California. All rights reserved.␊ |
4 | *␊ |
5 | * Redistribution and use in source and binary forms, with or without␊ |
6 | * modification, are permitted provided that the following conditions␊ |
7 | * are met:␊ |
8 | * 1. Redistributions of source code must retain the above copyright␊ |
9 | * notice, this list of conditions and the following disclaimer.␊ |
10 | * 2. Redistributions in binary form must reproduce the above copyright␊ |
11 | * notice, this list of conditions and the following disclaimer in the␊ |
12 | * documentation and/or other materials provided with the distribution.␊ |
13 | * 4. Neither the name of the University nor the names of its contributors␊ |
14 | * may be used to endorse or promote products derived from this software␊ |
15 | * without specific prior written permission.␊ |
16 | *␊ |
17 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND␊ |
18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE␊ |
19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE␊ |
20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE␊ |
21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL␊ |
22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS␊ |
23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)␊ |
24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT␊ |
25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY␊ |
26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF␊ |
27 | * SUCH DAMAGE.␊ |
28 | *␊ |
29 | * Posix rand_r function added May 1999 by Wes Peters <wes@softweyr.com>.␊ |
30 | */␊ |
31 | ␊ |
32 | #if defined(LIBC_SCCS) && !defined(lint)␊ |
33 | static char sccsid[] = "@(#)rand.c␉8.1 (Berkeley) 6/14/93";␊ |
34 | #endif /* LIBC_SCCS and not lint */␊ |
35 | #include <sys/cdefs.h>␊ |
36 | __FBSDID("$FreeBSD: src/lib/libc/stdlib/rand.c,v 1.17 2007/12/11 20:39:32 ache Exp $");␊ |
37 | ␊ |
38 | #ifdef TEST␊ |
39 | #include <stdio.h>␊ |
40 | #else␊ |
41 | #include "libsaio.h"␊ |
42 | #endif /* TEST */␊ |
43 | ␊ |
44 | static int␊ |
45 | do_rand(unsigned long *ctx)␊ |
46 | {␊ |
47 | #ifdef USE_WEAK_SEEDING␊ |
48 | /*␊ |
49 | * Historic implementation compatibility.␊ |
50 | * The random sequences do not vary much with the seed,␊ |
51 | * even with overflowing.␊ |
52 | */␊ |
53 | ␉return ((*ctx = *ctx * 1103515245 + 12345) % ((u_long)RAND_MAX + 1));␊ |
54 | #else /* !USE_WEAK_SEEDING */␊ |
55 | /*␊ |
56 | * Compute x = (7^5 * x) mod (2^31 - 1)␊ |
57 | * without overflowing 31 bits:␊ |
58 | * (2^31 - 1) = 127773 * (7^5) + 2836␊ |
59 | * From "Random number generators: good ones are hard to find",␊ |
60 | * Park and Miller, Communications of the ACM, vol. 31, no. 10,␊ |
61 | * October 1988, p. 1195.␊ |
62 | */␊ |
63 | ␉long hi, lo, x;␊ |
64 | ␊ |
65 | ␉/* Can't be initialized with 0, so use another value. */␊ |
66 | ␉if (*ctx == 0)␊ |
67 | ␉␉*ctx = 123459876;␊ |
68 | ␉hi = *ctx / 127773;␊ |
69 | ␉lo = *ctx % 127773;␊ |
70 | ␉x = 16807 * lo - 2836 * hi;␊ |
71 | ␉if (x < 0)␊ |
72 | ␉␉x += 0x7fffffff;␊ |
73 | ␉return ((*ctx = x) % ((u_long)RAND_MAX + 1));␊ |
74 | #endif /* !USE_WEAK_SEEDING */␊ |
75 | }␊ |
76 | ␊ |
77 | ␊ |
78 | int␊ |
79 | rand_r(unsigned int *ctx)␊ |
80 | {␊ |
81 | ␉u_long val = (u_long) *ctx;␊ |
82 | ␉int r = do_rand(&val);␊ |
83 | ␊ |
84 | ␉*ctx = (unsigned int) val;␊ |
85 | ␉return (r);␊ |
86 | }␊ |
87 | ␊ |
88 | ␊ |
89 | static u_long next = 1;␊ |
90 | ␊ |
91 | int␊ |
92 | rand()␊ |
93 | {␊ |
94 | ␉return (do_rand(&next));␊ |
95 | }␊ |
96 | ␊ |
97 | void␊ |
98 | srand(seed)␊ |
99 | u_int seed;␊ |
100 | {␊ |
101 | ␉next = seed;␊ |
102 | }␊ |
103 | ␊ |
104 | ␊ |
105 | #ifdef TEST␊ |
106 | ␊ |
107 | main()␊ |
108 | {␊ |
109 | int i;␊ |
110 | unsigned myseed;␊ |
111 | ␊ |
112 | printf("seeding rand with 0x19610910: \n");␊ |
113 | srand(0x19610910);␊ |
114 | ␊ |
115 | printf("generating three pseudo-random numbers:\n");␊ |
116 | for (i = 0; i < 3; i++)␊ |
117 | {␊ |
118 | printf("next random number = %d\n", rand());␊ |
119 | }␊ |
120 | ␊ |
121 | printf("generating the same sequence with rand_r:\n");␊ |
122 | myseed = 0x19610910;␊ |
123 | for (i = 0; i < 3; i++)␊ |
124 | {␊ |
125 | printf("next random number = %d\n", rand_r(&myseed));␊ |
126 | }␊ |
127 | ␊ |
128 | return 0;␊ |
129 | }␊ |
130 | ␊ |
131 | #endif /* TEST */␊ |
132 | |