1 /* ============================================================
2  *
3  * This file is a part of digiKam project
4  * https://www.digikam.org
5  *
6  * Date        : 2010-11-03
7  * Description : Generating random numbers
8  *
9  * Copyright (C) 2010-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
10  *
11  * This program is free software; you can redistribute it
12  * and/or modify it under the terms of the GNU General
13  * Public License as published by the Free Software Foundation;
14  * either version 2, or (at your option)
15  * any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * ============================================================ */
23 
24 #ifndef DIGIKAM_RANDOM_NUMBER_GENERATOR_H
25 #define DIGIKAM_RANDOM_NUMBER_GENERATOR_H
26 
27 // Qt includes
28 
29 #include <QByteArray>
30 
31 // Local includes
32 
33 #include "digikam_export.h"
34 
35 namespace Digikam
36 {
37 
38 class DIGIKAM_EXPORT NonDeterministicRandomData : public QByteArray
39 {
40 public:
41 
42     /**
43      * Constructs a QByteArray of given byte size
44      * filled with non-deterministic random data.
45      * For larger quantities of data,
46      * prefer using a RandomNumberGenerator seeded
47      * with non-deterministic data.
48      */
49     explicit NonDeterministicRandomData(int size);
50 };
51 
52 // --------------------------------------------------------------------
53 
54 /**
55  * This class differs from standard pseudo
56  * random number generators (rand()) in these points:
57  * - it uses a specified, independently implemented algorithm
58  *   identical across platforms
59  * - provides access to the used seed
60  * - it can thus guarantee replayable sequences
61  * - it provides convenient seeding of varying quality
62  */
63 class DIGIKAM_EXPORT RandomNumberGenerator
64 {
65 public:
66 
67     /**
68      * Constructs a random number generator that is seeded
69      * with a constant value. It is recommended to call a seed method
70      * after construction.
71      */
72     explicit RandomNumberGenerator();
73     ~RandomNumberGenerator();
74 
75     /**
76      * Seeds the generator from a non-deterministic
77      * random number generator. This is the most secure
78      * seeding method.
79      * Returns the new currentSeed().
80      */
81     quint32 seedNonDeterministic();
82 
83     /**
84      * Seeds the generator by current time. This is common practice
85      * and good enough for most purposes.
86      * Returns the new currentSeed().
87      */
88     quint32 seedByTime();
89 
90     /**
91      * Produces a non-deterministic seed, as used by seedNonDeterministic()
92      */
93     static quint32 nonDeterministicSeed();
94 
95     /**
96      * Produces a seed that includes at least the time as source
97      * of random data
98      */
99     static quint32 timeSeed();
100 
101     /**
102      * Seeds the generator with the given value.
103      * This is not meant to be called with a constant value,
104      * but with a value retrieved from currentSeed() on a previous run.
105      * Across platforms, the same sequence of random numbers will be
106      * generated for the same seed.
107      */
108     void seed(quint32 seed);
109 
110     /**
111      * Seeds the generator again with the currentSeed().
112      * This is not a no-op, rather, the sequence of random numbers
113      * starts again from its beginning after each re-seed.
114      * Equivalent to seed(currentSeed())
115      */
116     void reseed();
117 
118     /**
119      * Retrieves the current seed. Can be used for seed(quint32)
120      * to replay the results again.
121      */
122     quint32 currentSeed() const;
123 
124     /**
125      * Returns a random integer in the interval [min, max]
126      * (including min and max).
127      * Warning: this method is non re-entrant.
128      */
129     int number(int min, int max);
130 
131     /**
132      * Returns a random double in the interval [min, max)
133      * (including min, excluding max)
134      * Warning: this method is non re-entrant.
135      */
136     double number(double min, double max);
137 
138     /**
139      * Returns true with a probability of p
140      * (where p shall be in the interval [0, 1])
141      * Warning: this method is non re-entrant.
142      */
143     bool yesOrNo(double p);
144 
145 private:
146 
147     // Disable
148     RandomNumberGenerator(const RandomNumberGenerator&)            = delete;
149     RandomNumberGenerator& operator=(const RandomNumberGenerator&) = delete;
150 
151 private:
152 
153     class Private;
154     Private* const d;
155 };
156 
157 } // namespace Digikam
158 
159 #endif // DIGIKAM_RANDOM_NUMBER_GENERATOR_H
160