fix memory leak
[trinity.git] / random.c
blob7def9ff7c61c9995ded3a95e6b7cc4ec88eaee5b
1 /*
2 * Routines to get randomness.
3 */
4 #include <syslog.h>
5 #include <unistd.h>
6 #include <stdlib.h>
7 #include <sys/types.h>
8 #include <limits.h>
9 #include "pids.h"
10 #include "random.h"
11 #include "sanitise.h" // interesting_numbers
12 #include "types.h"
14 unsigned int rand_bool(void)
16 return rand() % 2;
19 static unsigned int rand_single_bit(unsigned char size)
21 return (1L << (rand() % size));
25 * set N bits, where N= rand(0 - WORDSIZE/2)
27 static unsigned long randbits(int limit)
29 unsigned int num = rand() % limit / 2;
30 unsigned int i;
31 unsigned long r = 0;
33 for (i = 0; i < num; i++)
34 r |= (1 << (rand() % (limit - 1)));
36 return r;
40 * Based on very similar routine stolen from iknowthis. Thanks Tavis.
42 static unsigned long taviso(void)
44 unsigned long r = 0;
46 switch (rand() % 4) {
47 case 0: r = rand() & rand();
48 #if __WORDSIZE == 64
49 r <<= 32;
50 r |= rand() & rand();
51 #endif
52 break;
54 case 1: r = rand() % rand();
55 #if __WORDSIZE == 64
56 r <<= 32;
57 r |= rand() % rand();
58 #endif
59 break;
61 case 2: r = rand() | rand();
62 #if __WORDSIZE == 64
63 r <<= 32;
64 r |= rand() | rand();
65 #endif
66 break;
68 case 3: r = rand();
69 #if __WORDSIZE == 64
70 r <<= 32;
71 r |= rand();
72 #endif
73 break;
75 default:
76 break;
79 return r;
83 * Pick 8 random bytes, and concatenate them into a long.
85 static unsigned long rand8x8(void)
87 unsigned long r = 0UL;
88 unsigned int i;
90 for (i = (rand() % 7) + 1; i > 0; --i)
91 r = (r << 8) | rand() % 256;
93 return r;
97 * Pick 1 random byte, and repeat it through a long.
99 static unsigned long rept8(unsigned int num)
101 unsigned long r = 0UL;
102 unsigned int i;
103 unsigned char c;
105 c = rand() % 256;
106 for (i = rand() % (num - 1) ; i > 0; --i)
107 r = (r << 8) | c;
109 return r;
113 * "selector" function for 32bit random.
114 * only called from rand32()
116 static unsigned int __rand32(void)
118 unsigned long r = 0;
120 switch (rand() % 7) {
121 case 0: r = rand_single_bit(32);
122 break;
123 case 1: r = randbits(32);
124 break;
125 case 2: r = rand();
126 break;
127 case 3: r = taviso();
128 break;
129 case 4: r = rand8x8();
130 break;
131 case 5: r = rept8(4);
132 break;
133 case 6: return get_interesting_32bit_value();
134 default:
135 break;
138 return r;
142 * Generate, and munge a 32bit number.
144 unsigned int rand32(void)
146 unsigned long r = 0;
148 r = __rand32();
150 if (rand_bool()) {
151 unsigned int i;
152 unsigned int rounds;
154 /* mangle it. */
155 rounds = rand() % 3;
156 for (i = 0; i < rounds; i++) {
157 switch (rand_bool()) {
158 case 0: r |= __rand32();
159 break;
160 case 1: r ^= __rand32();
161 break;
162 default:
163 break;
168 /* Sometimes deduct it from INT_MAX */
169 if (rand_bool())
170 r = INT_MAX - r;
172 /* Sometimes flip sign */
173 if (rand_bool())
174 r |= (1L << 31);
176 /* we might get lucky if something is counting ints/longs etc. */
177 if (rand() % 100 < 25) {
178 int _div = 1 << ((rand() % 4) + 1); /* 2,4,8 or 16 */
179 r /= _div;
182 /* limit the size */
183 switch (rand() % 4) {
184 case 0: r &= 0xff;
185 break;
186 case 1: r &= 0xffff;
187 break;
188 case 2: r &= 0xffffff;
189 break;
190 default:
191 break;
194 return r;
198 * Generate and munge a 64bit number.
200 u64 rand64(void)
202 unsigned long r = 0;
204 if (rand_bool()) {
205 /* 32-bit ranges. */
206 r = rand32();
208 } else {
209 /* 33:64-bit ranges. */
210 switch (rand() % 7) {
211 case 0: r = rand_single_bit(64);
212 break;
213 case 1: r = randbits(64);
214 break;
215 case 2: r = rand32() | rand32() << 31;
216 break;
217 case 3: r = taviso();
218 break;
219 case 4: r = rand8x8();
220 break;
221 case 5: r = rept8(8);
222 break;
223 /* Sometimes pick a not-so-random number. */
224 case 6: return get_interesting_value();
225 default:
226 break;
229 /* limit the size */
230 switch (rand() % 4) {
231 case 0: r &= 0x000000ffffffffffULL;
232 break;
233 case 1: r &= 0x0000ffffffffffffULL;
234 break;
235 case 2: r &= 0x00ffffffffffffffULL;
236 break;
237 default:
238 break;
242 /* Sometimes invert the generated number. */
243 if (rand_bool())
244 r = ~r;
246 /* increase distribution in MSB */
247 if ((rand() % 10)) {
248 unsigned int i;
249 unsigned int rounds;
251 rounds = rand() % 4;
252 for (i = 0; i < rounds; i++)
253 r |= (1L << ((__WORDSIZE - 1) - (rand() % 8)));
256 /* randomly flip sign bit. */
257 if (rand_bool())
258 r |= (1L << (__WORDSIZE - 1));
260 return r;