ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
simpleRandom.h
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file simpleRandom.h
1 #ifndef __SIMPLERANDOM_H__
2 #define __SIMPLERANDOM_H__
3 
4 /*
5  * After becoming frustrated with the lack of a standalone, portable,
6  * decent random number generator, I decided to make one based on a
7  * cryptographic one-way hash function. I chose MD5 since it is fast
8  * and free source was readily available. More cryptographically
9  * secure hash functions are available (e.g. SHA-1), but for the
10  * purposes of a rand/random/erand48 replacement, MD5 should be more
11  * than sufficient.
12  *
13  * MD5 takes an arbitrary amount of input and yields a 16 byte hash.
14  * This RNG continually MD5's a 16 byte digest, and uses the bottom N
15  * bits as the random number yielded, where N is just large enough to
16  * include the largest random number desired.
17  *
18  * To yield a random number between 0 and r:
19  *
20  * create mask which has enough bits to include all of r
21  * (for example, if r is 100, mask would be 0x7F)
22  *
23  * do {
24  * digest = MD5(digest)
25  * number = digest & mask
26  * } while (number > r)
27  *
28  * The digest should be loaded and saved to a disk file between
29  * invocations of a program using the RNG.
30  *
31  * Random functions appear after the included MD5 code.
32  *
33  * Send comments to: skrenta@pbm.com (Rich Skrenta)
34  */
35 
36 
37 /*****************************************************************/
38 
39 /*
40  * This code implements the MD5 message-digest algorithm.
41  * The algorithm is due to Ron Rivest. This code was
42  * written by Colin Plumb in 1993, no copyright is claimed.
43  * This code is in the public domain; do with it what you wish.
44  *
45  * Equivalent code is available from RSA Data Security, Inc.
46  * This code has been tested against that, and is equivalent,
47  * except that you don't need to include two pages of legalese
48  * with every copy.
49  *
50  * To compute the message digest of a chunk of bytes, declare an
51  * MD5Context structure, pass it to MD5Init, call MD5Update as
52  * needed on buffers full of bytes, and then call MD5Final, which
53  * will fill a supplied 16-byte array with the digest.
54  */
55 
56 
57 typedef unsigned int word32;
58 typedef unsigned char xbyte;
59 
60 struct xMD5Context {
61  word32 buf[4];
63  word32 in[16];
64 };
65 
66 class simpleRandom {
67 public:
68  simpleRandom();
69  simpleRandom(const int iseed);
70 
71  float gauss(const float mean, const float sigma);
72  float rnd(int low, int high);
73 
74 private:
75 
76  void byteSwap(word32 *buf, unsigned words);
77  void xMD5Init(struct xMD5Context *ctx);
78  void xMD5Update(struct xMD5Context *ctx, xbyte const *buf, unsigned int len);
79  void xMD5Final(xbyte digest[16], struct xMD5Context *ctx);
80  void xMD5Transform(word32 buf[4], word32 const in[16]);
81  void MD5(xbyte *dest, const xbyte *orig, unsigned int len);
82  void load_seed();
83 
84  unsigned int digest[4];
85 
86 };
87 #endif
88