root/misc/rand_range.c

Revision 972, 2.9 kB (checked in by alpt, 2 years ago)

stuff

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <time.h>
4 #include <sys/types.h>
5 #include <unistd.h>
6
7 /*\
8  *
9  *
10  *      * * *  Random functions  * * *
11  *
12  *
13 \*/
14
15 void xsrand(void);
16
17 #define URANDOM_DEVICE                  "/dev/urandom"
18
19 unsigned short int _rnd_rng_state[3];
20 FILE *_rnd_urandom_fd=0;
21
22 /*
23  * init_rand
24  *
25  * Initialize this code
26  */
27 void init_rand(void)
28 {
29         if(!_rnd_urandom_fd)
30                 _rnd_urandom_fd=fopen(URANDOM_DEVICE, "r");
31         xsrand();
32 }
33
34 void close_rand(void)
35 {
36         if(_rnd_urandom_fd)
37                 fclose(_rnd_urandom_fd);
38 }
39
40 /*
41  * get_time_xorred
42  *
43  * It returns a real random seed.
44  *
45  * The idea is simple: the microseconds of the current time returned by
46  * gettimeofday() mess up everything.
47  * It is impossible to know what `tv_usec' will be in a given instant.
48  * The returned value is the `tv_usec' xorred with `tv_sec'.
49  *
50  * You should not use get_time_xorred() to get a random number, because the
51  * returned values are not uniformly distributed.
52  * The correct use of this function is to set the random seed using srand(),
53  * seed48(), _only if_ /dev/urandom is not present in the OS.
54  */
55 int get_time_xorred(void)
56 {
57         struct timeval t;
58         gettimeofday(&t, 0);
59
60         return t.tv_usec ^ t.tv_sec;
61 }
62 void _xsrand(void)
63 {
64         unsigned int seed;
65
66         if(_rnd_urandom_fd)
67                 fread(&seed, sizeof(unsigned int), 1, _rnd_urandom_fd);
68         else
69                 seed=getpid() ^ clock() ^ get_time_xorred();
70
71         srand(seed);
72 }
73
74 void _xsrand48(void)
75 {
76         if(_rnd_urandom_fd)
77                 fread(_rnd_rng_state, sizeof(_rnd_rng_state), 1, _rnd_urandom_fd);
78         else {
79                 long sc=0;
80
81 #ifdef _SC_AVPHYS_PAGES
82                 sc=sysconf(_SC_AVPHYS_PAGES);
83 #endif
84
85                 _rnd_rng_state[0]=clock() ^ getpid() ^ get_time_xorred();
86                 _rnd_rng_state[1]=clock() ^ sc ^ get_time_xorred();
87                 _rnd_rng_state[2]=get_time_xorred();
88         }
89
90         seed48(_rnd_rng_state);
91 }
92
93 /*
94  * xsrand
95  *
96  * It sets the random seed with a pseudo random number
97  */
98 void xsrand(void)
99 {
100 //XXX: activate when necessary  _xsrand();
101         _xsrand48();
102 }
103
104 inline long int xrand_fast(void)
105 {
106         return nrand48(_rnd_rng_state);
107 }
108
109 long int xrand(void)
110 {
111         long int r=0;
112
113         if(_rnd_urandom_fd)
114                 fread(&r, sizeof(long int), 1, _rnd_urandom_fd);
115         else
116                 r=xrand_fast();
117
118         return abs(r);
119 }
120
121 /*
122  * rand_range: It returns a random number x which is _min <= x <= _max
123  */
124 inline int rand_range(int _min, int _max)
125 {
126         return ((int)xrand()%(_max - _min + 1)) + _min;
127 }
128
129
130 int main(int argc, char **argv)
131 {
132         unsigned int min, max;
133
134         if(argc<2) {
135                 printf("Usage:\n"
136                         "       `rand_range [min] max' returns a random\n"
137                         "        number between `min' (or 0) and `max'\n"
138                         "        (inclusive)\n"
139                         "\n"
140                         "       `rand_range rand' returns a random "
141                         "        number between 0 and 2^32-1\n");
142                 exit(1);
143         } else if(argc==2) {
144                 min=0;
145                 if(!strcasecmp(argv[1], "rand"))
146                         max=1<<32-1;
147                 else
148                         max=atoi(argv[1]);
149         } else {
150                 min=atoi(argv[1]);
151                 max=atoi(argv[2]);
152         }
153
154         init_rand();
155         printf("%ld\n", (unsigned int)rand_range(min, max));
156         close_rand();
157         exit(0);
158 }
Note: See TracBrowser for help on using the browser.