source: Project Repository/src/random.h @ 1

Revision 1, 7.1 KB checked in by pchapin, 8 years ago (diff)

Added the HWRNG project.

Line 
1/****************************************************************************
2FILE          : random.h
3LAST REVISION : 2005-11-21
4SUBJECT       : Interface to random number abstract class.
5PROGRAMMER    : (C) Copyright 2005 by Peter C. Chapin
6
7This file contains the interface to a random number generating class. For
8brevity it also contains the definitions of two implementation classes (it
9would be more typical for each implementation class to have a header of
10its own).
11
12Please send comments or bug reports to
13
14     Peter C. Chapin
15     Electrical and Computer Engineering Technology
16     Vermont Technical College
17     Randolph Center, VT 05061
18     pchapin@ecet.vtc.edu
19****************************************************************************/
20
21#ifndef RANDOM_H
22#define RANDOM_H
23
24#include <cstdlib>
25
26//! Namespace that contains the contents of the Random Library.
27namespace rnd {
28
29  //! Abstract base class for random number generators.
30  /*!
31   * This class is intended to provide an abstract interface to all
32   * random number generator objects that return natural numbers in the
33   * range 0 to some maximum value.
34   *
35   * \todo It might make sense to use a type such as uint32_t for the
36   * random numbers rather than unsigned int as is currently the case.
37   * This would promote portability to 16 bit (or smaller) platforms.
38   */
39  class random {
40  public:
41
42    virtual ~random() { }
43
44    //! Extract the next random number from the object.
45    virtual unsigned next() = 0;
46
47    //! Returns the maximum possible value returned by next().
48    virtual unsigned max() = 0;
49
50    //! Returns a random number in the range [L .. H] from the object.
51    /*!
52     * This method uses the underlying generator to compute a random
53     * natural number in the given range. Each call on this method
54     * invokes exactly one call to the underlying next() method. This
55     * method for convenience.
56     *
57     * \param L The lower limit of the output range.
58     * \param H The upper limit of the output range.
59     * \return A number in the specified range. H and L are included in
60     * the range.
61     */
62    unsigned next(unsigned L, unsigned H)
63      { return (next() % (H - L + 1)) + L; }
64  };
65
66
67  //! Random bit generator wrapper class (scanner).
68  /*!
69   * This class is a wrapper around class random that returns individual
70   * bits. It works by scanning down the numbers returned by the
71   * underlying generator and returning the bits it finds there, one at
72   * a time.
73   *
74   * \warning If the underlying generator has a maximum value that is
75   * not a power of two, the output of this generator will have bias.
76   * This is because the most significant bit of the output of the
77   * underlying generator will not be occuring with frequency 0.5.
78   */
79  class bit_random : public random {
80  private:
81    random &generator;
82    unsigned current;
83    unsigned mask;
84
85  public:
86    /*!
87     * \param g A reference to a random number generator that is used as
88     * the source of random natural numbers.
89     */
90    bit_random(random &g) : generator(g) { mask = 0; }
91   ~bit_random() { }
92
93    virtual unsigned next();
94    virtual unsigned max()
95      { return 1; }
96  };
97
98  //! Random bit generator wrapper class (LSB).
99  /*!
100   * This class is a wrapper around class random that returns individual
101   * bits. It works by returning the least significant bit of each
102   * number returned by the underlying generator.
103   *
104   * \warning Many PRNGs are not good at randomizing the least
105   * significant bits of each output number.
106   */
107  class lsbbit_random : public random {
108  private:
109    random &generator;
110
111  public:
112    /*!
113     * \param g A reference to a random number generator that is used as
114     * the source of random natural numbers.
115     */
116    lsbbit_random(random &g) : generator(g) { }
117   ~lsbbit_random() { }
118
119    virtual unsigned next()
120      { return generator.next() & 0x1; }
121
122    virtual unsigned max()
123      { return 1; }
124  };
125
126
127  //! Abstract base class for seeded random number generators.
128  class seeded_random : public random {
129  public:
130
131    //! Provide a seed value to the random number generator.
132    /*!
133     * Random number generators that require a seed value include all
134     * PRNGs. The seed is used as the starting point of the pseudo
135     * random sequence. A particular sequence can be repeated by
136     * providing the same seed.
137     *
138     * \param s The seed value. This value is usually required to be in
139     * the same range as the generator's output, but that does not need
140     * to be the case in general.
141     *
142     * \warning If an attacker can guess the seed value used, the
143     * attacker can compute the pseudo random sequence generated. Thus
144     * in security sensitive applications, seed values must be choosen
145     * in an unguessable way.
146     */
147    virtual void seed(unsigned s) = 0;
148
149    //! Uses the current time of day to generate a seed.
150    /*!
151     * \warning Be careful creating too many objects that are seeded
152     * this way. If you seed them all quickly enough they may get the
153     * same seed. Even if you seed them slowly, there may be resonances
154     * between your program and the system clock.
155     *
156     * \warning The current time is too guessable for use in security
157     * sensitive applications.
158     */
159    void time_seed();
160  };
161
162
163  //! Wrapper around the standard C library's PRNG.
164  /*!
165   * \warning Because the standard random number generator keeps its
166   * seed in a static object in the library, all objects of type
167   * standard_random are interrelated. Be careful using this class!
168   */
169  class standard_random : public seeded_random {
170  public:
171    virtual ~standard_random() { }
172
173    virtual unsigned next()
174      { return static_cast<unsigned>(std::rand()); }
175
176    virtual unsigned max()
177      { return static_cast<unsigned>(RAND_MAX); }
178
179    virtual void seed(unsigned s)
180      { std::srand(s); }
181  };
182
183
184  //! Linear congruential PRNG.
185  /*!
186   * This generator has a period of 1771875 states. All objects from this
187   * class are independent and have different internal states.
188   *
189   * \warning Like all linear congruential generators, this generator is
190   * not suitable for use in security sensitive applications.
191   *
192   * \todo Generalize this class so that the user can provide the
193   * constants used in the linear congruential computations. It might
194   * also be nice to provide several "defaults" (selectable with a
195   * method call perhaps) so that users can use the generator without
196   * much fuss.
197   */
198  class linear_congruential : public seeded_random {
199  private:
200    unsigned long X;    // The "current value" of the generator.
201
202  public:
203    virtual ~linear_congruential() { }
204
205    // The constants below ensure maximum period and their values take
206    // advantage of the range on a 32 bit unsigned quantity.
207    //
208    virtual unsigned next()
209      { return X = ((2416UL * X) + 374441UL) % 1771875UL; }
210
211    virtual unsigned max()
212      { return 1771874; }
213 
214    virtual void seed(unsigned s)
215      { X = s; }
216  };
217
218}
219
220#endif
Note: See TracBrowser for help on using the repository browser.