check if uid changes across syscalls.
[trinity.git] / random.c
blob0d9872872905f5b323adb81203171d3f3d022030
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 /* limit the size */
177 switch (rand() % 4) {
178 case 0: r &= 0xff;
179 break;
180 case 1: r &= 0xffff;
181 break;
182 case 2: r &= 0xffffff;
183 break;
184 default:
185 break;
188 return r;
192 * Generate and munge a 64bit number.
194 u64 rand64(void)
196 unsigned long r = 0;
198 if (rand_bool()) {
199 /* 32-bit ranges. */
200 r = rand32();
202 } else {
203 /* 33:64-bit ranges. */
204 switch (rand() % 7) {
205 case 0: r = rand_single_bit(64);
206 break;
207 case 1: r = randbits(64);
208 break;
209 case 2: r = rand32() | rand32() << 31;
210 break;
211 case 3: r = taviso();
212 break;
213 case 4: r = rand8x8();
214 break;
215 case 5: r = rept8(8);
216 break;
217 /* Sometimes pick a not-so-random number. */
218 case 6: return get_interesting_value();
219 default:
220 break;
223 /* limit the size */
224 switch (rand() % 4) {
225 case 0: r &= 0x000000ffffffffffULL;
226 break;
227 case 1: r &= 0x0000ffffffffffffULL;
228 break;
229 case 2: r &= 0x00ffffffffffffffULL;
230 break;
231 default:
232 break;
236 /* Sometimes invert the generated number. */
237 if (rand_bool())
238 r = ~r;
240 /* increase distribution in MSB */
241 if ((rand() % 10)) {
242 unsigned int i;
243 unsigned int rounds;
245 rounds = rand() % 4;
246 for (i = 0; i < rounds; i++)
247 r |= (1L << ((__WORDSIZE - 1) - (rand() % 8)));
250 /* randomly flip sign bit. */
251 if (rand_bool())
252 r |= (1L << (__WORDSIZE - 1));
254 return r;