BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslh_seedgenerator.h
Go to the documentation of this file.
1/// @file bslh_seedgenerator.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslh_seedgenerator.h -*-C++-*-
8#ifndef INCLUDED_BSLH_SEEDGENERATOR
9#define INCLUDED_BSLH_SEEDGENERATOR
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslh_seedgenerator bslh_seedgenerator
15/// @brief Provide a class to generate arbitrary length seeds for algorithms.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslh
19/// @{
20/// @addtogroup bslh_seedgenerator
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslh_seedgenerator-purpose"> Purpose</a>
25/// * <a href="#bslh_seedgenerator-classes"> Classes </a>
26/// * <a href="#bslh_seedgenerator-description"> Description </a>
27/// * <a href="#bslh_seedgenerator-requirements-on-rng"> Requirements on RNG </a>
28/// * <a href="#bslh_seedgenerator-usage"> Usage </a>
29/// * <a href="#bslh_seedgenerator-example-seeding-hashing-algorithms-requiring-different-seed-sizes"> Example: Seeding Hashing Algorithms Requiring Different Seed Sizes </a>
30///
31/// # Purpose {#bslh_seedgenerator-purpose}
32/// Provide a class to generate arbitrary length seeds for algorithms.
33///
34/// # Classes {#bslh_seedgenerator-classes}
35///
36/// - bslh::SeedGenerator: generator for arbitrary length seeds
37///
38/// @see
39///
40/// # Description {#bslh_seedgenerator-description}
41/// This component provides a class, `bslh::SeedGenerator`, which
42/// utilizes a user-supplied Random Number Generator (RNG) to generate arbitrary
43/// length seeds. The quality of the seeds will only be as good as the quality
44/// of the supplied RNG. A cryptographically secure RNG must be supplied in
45/// order for `SeedGenerator` to produce seeds suitable for a cryptographically
46/// secure algorithm.
47///
48/// This class satisfies the requirements for a seed generator, defined in
49/// `bslh_seededhash.h`. More information can be found in the package level
50/// documentation for `bslh` (internal users can also find information here
51/// {TEAM BDE:USING MODULAR HASHING<GO>})
52///
53/// ## Requirements on RNG {#bslh_seedgenerator-requirements-on-rng}
54///
55///
56/// The (template parameter) type `RANDOM_NUM_GEN` shall be a class that
57/// provides a type alias `result_type` and exposes an `operator()` that returns
58/// a result of type `result_type`. The value returned by `operator()` shall be
59/// random bits, the quality of which can be defined by `RANDOM_NUM_GEN`.
60/// `RANDOM_NUM_GEN` shall also be default and copy constructible.
61///
62/// ## Usage {#bslh_seedgenerator-usage}
63///
64///
65/// This section illustrates intended usage of this component.
66///
67/// ### Example: Seeding Hashing Algorithms Requiring Different Seed Sizes {#bslh_seedgenerator-example-seeding-hashing-algorithms-requiring-different-seed-sizes}
68///
69///
70/// Suppose we have a number of hashing algorithms that all require different
71/// length seeds. Some require 32 bits, some require 64 bits, some even require
72/// 1024 bits. We want to generate all these seeds in the same way, but we do
73/// not want to keep manually generating seeds of different sizes for these
74/// algorithms. Moreover, we want to be able to use all these algorithms
75/// through a general purpose functor. To accomplish this, we give all our
76/// algorithm the same interface and supply a seed generator, which can create
77/// any size seed that the algorithms require.
78///
79/// First, we write our first hashing algorithm, which accepts a 32-bit seed and
80/// returns a 32-bit unsigned int.
81/// @code
82/// class Seeded32BitHashingAlgorithm {
83/// // This class is a functor that implements a hashing algorithm seeded
84/// // with 32 bits.
85///
86/// public:
87/// typedef unsigned result_type; // Type of the hash returned
88/// enum { k_SEED_LENGTH = 4 }; // Seed length in bytes
89///
90/// private:
91/// const char *d_seed; // Seed used in the generation of hashes
92///
93/// public:
94/// explicit Seeded32BitHashingAlgorithm(const char *seed);
95/// // Construct a 'Seeded32BitHashingAlgorithm' that will use the
96/// // first 4 bytes of the specified 'seed' to seed the algorithm.
97///
98/// result_type operator()(const char *data, size_t length);
99/// // Return a hash of the specified 'length' bytes of 'data'.
100/// };
101/// @endcode
102/// Then, we define another hashing algorithm, which accepts a 64-bit seed and
103/// returns a 32-bit unsigned int
104/// @code
105/// class Seeded64BitHashingAlgorithm {
106/// // This class is a functor that implements a hashing algorithm seeded
107/// // with 64 bits.
108///
109/// public:
110/// typedef unsigned result_type; // Type of the hash returned
111/// enum { k_SEED_LENGTH = 8 }; // Seed length in bytes
112///
113/// private:
114/// const char *d_seed; // Seed used in the generation of hashes
115///
116/// public:
117/// explicit Seeded64BitHashingAlgorithm(const char *seed);
118/// // Construct a 'Seeded64BitHashingAlgorithm' that will use the
119/// // first 8 bytes of the specified 'seed' to seed the algorithm.
120///
121/// result_type operator()(const char *data, size_t length);
122/// // Return a hash of the specified 'length' bytes of 'data'.
123/// };
124/// @endcode
125/// Next, we define a final hashing algorithm, which accepts a 1024-bit seed and
126/// returns a 32-bit unsigned int
127/// @code
128/// class Seeded1024BitHashingAlgorithm {
129/// // This class is a functor that implements a hashing algorithm seeded
130/// // with 1024 bits.
131///
132/// public:
133/// typedef unsigned result_type; // Type of the hash returned
134/// enum { k_SEED_LENGTH = 128 }; // Seed length in bytes
135///
136/// private:
137/// const char *d_seed; // Seed used in the generation of hashes
138///
139/// public:
140/// explicit Seeded1024BitHashingAlgorithm(const char *seed);
141/// // Construct a 'Seeded1024BitHashingAlgorithm' that will use the
142/// // first 128 bytes of the specified 'seed' to seed the algorithm.
143///
144/// result_type operator()(const char *data, size_t length);
145/// // Return a hash of the specified 'length' bytes of 'data'.
146/// };
147/// @endcode
148/// Then, we declare our functor, `SeededHash`, which will take a seed
149/// generator, and be able to run any of our hashing algorithms by generating
150/// the correct size seed with the seed generator.
151/// @code
152/// template <class HASH_ALGORITHM>
153/// class SeededHash {
154/// // This class template implements an interface similar to 'std::hash',
155/// // which will used the (template parameter) type 'SEED_GENERATOR' and
156/// // 'HASH_ALGORITHM' to compute hashes.
157///
158/// public:
159/// typedef typename HASH_ALGORITHM::result_type result_type;
160/// // Type of the hash that will be returned.
161///
162/// private:
163/// char seed[HASH_ALGORITHM::k_SEED_LENGTH];
164/// // Stores the seed that will be used to run the (template
165/// // parameter) type 'HASH_ALGORITHM'
166///
167/// public:
168/// template<class SEED_GENERATOR>
169/// SeededHash(SEED_GENERATOR seedGenerator);
170/// //Create a 'SeededHash' and generate a seed using the specified
171/// //'seedGenerator'.
172///
173/// result_type operator()(const char *data, size_t length) const;
174/// // Returns a hash generated by the (template parameter) type
175/// // 'HASH_ALGORITHM' for the specified 'length' bytes of 'data'.
176///
177/// };
178/// @endcode
179/// Next, we define our constructor where we actually use `bslh::SeedGenerator`.
180/// `bslh::SeedGenerator` allows us to create arbitrary length seeds to match
181/// the requirements of the above declared algorithms.
182/// @code
183/// template <class HASH_ALGORITHM>
184/// template<class SEED_GENERATOR>
185/// SeededHash<HASH_ALGORITHM>::SeededHash(SEED_GENERATOR seedGenerator) {
186/// seedGenerator.generateSeed(seed, HASH_ALGORITHM::k_SEED_LENGTH);
187/// }
188///
189/// template <class HASH_ALGORITHM>
190/// typename SeededHash<HASH_ALGORITHM>::result_type
191/// SeededHash<HASH_ALGORITHM>::operator()(const char *data,
192/// size_t length) const {
193/// HASH_ALGORITHM hashAlg(seed);
194/// return hashAlg(data, length);
195/// }
196/// @endcode
197/// Now, we generate some data that we want to hash.
198/// @code
199/// const char *data[] = { "asdf",
200/// "qwer",
201/// "gskgf",
202/// "ujkagad",
203/// "rwwfwe", };
204/// enum { NUM_STRINGS = sizeof data / sizeof *data };
205/// @endcode
206/// Finally, we can hash the data the same way using all of the different
207/// hashing algorithms. The seed generator allows us to abstract away the
208/// different requirements each algorithm has on seed size. Each algorithm will
209/// produce different output because it has been supplied with a different seed.
210/// @code
211/// MockRNG rng;
212/// SeedGenerator<MockRNG> seedGen(rng);
213/// SeededHash<Seeded32BitHashingAlgorithm> hashAlg32BitSeed(seedGen);
214/// SeededHash<Seeded64BitHashingAlgorithm> hashAlg64BitSeed(seedGen);
215/// SeededHash<Seeded1024BitHashingAlgorithm> hashAlg1024BitSeed(seedGen);
216///
217/// for (int i = 0; i < NUM_STRINGS; ++i) {
218/// unsigned int hash32BitSeed = hashAlg32BitSeed(data[i],
219/// strlen(data[i]));
220/// unsigned int hash64BitSeed = hashAlg64BitSeed(data[i],
221/// strlen(data[i]));
222/// unsigned int hash1024BitSeed = hashAlg1024BitSeed(data[i],
223/// strlen(data[i]));
224///
225/// if (veryVerbose) printf("Asserting hashes of %s come out"
226/// " different\n", data[i]);
227/// ASSERT(hash32BitSeed != hash64BitSeed);
228/// ASSERT(hash32BitSeed != hash1024BitSeed);
229/// ASSERT(hash1024BitSeed != hash64BitSeed);
230/// }
231/// @endcode
232/// @}
233/** @} */
234/** @} */
235
236/** @addtogroup bsl
237 * @{
238 */
239/** @addtogroup bslh
240 * @{
241 */
242/** @addtogroup bslh_seedgenerator
243 * @{
244 */
245
246#include <bslscm_version.h>
247
248#include <bsls_assert.h>
249
250#include <string.h> // for 'memcpy'
251#include <stddef.h> // for 'size_t'
252
253
254
255namespace bslh {
256
257 // =========================
258 // class bslh::SeedGenerator
259 // =========================
260
261/// This class template implements a seed generator which takes a user
262/// supplied random number generator and uses it to generate an arbitrary
263/// length seed. Note that this type inherits from the (template parameter)
264/// type `RANDOM_NUM_GEN` to take advantage of the empty-base optimization.
265template<class RANDOM_NUM_GEN>
266class SeedGenerator : private RANDOM_NUM_GEN {
267
268 private:
269 // PRIVATE TYPES
270
271 /// `result_type` is an alias for the value returned by a call to
272 /// `operator()` on the (template parameter) type `RNG`.
273 typedef typename RANDOM_NUM_GEN::result_type result_type;
274
275 // DATA
276
277 /// Size in bytes of the rng's output.
278 enum { k_RNGOUTPUTSIZE = sizeof(typename RANDOM_NUM_GEN::result_type)};
279
280 public:
281 // CREATORS
282
283 /// Create a `bslh::SeedGenerator` that will default construct the
284 /// parameterized `RNG` and use it to generate its seeds.
286
287 /// Create a `bslh::SeedGenerator` that will use the specified
288 /// `randomNumberGenerator` to generate its seeds.
289 explicit SeedGenerator(const RANDOM_NUM_GEN &randomNumberGenerator);
290
291 SeedGenerator(const SeedGenerator& original) = default;
292 // Create a 'bslh::SeedGenerator' object with a copy of the random
293 // number generator used by the specified 'original'.
294
295 ~SeedGenerator() = default;
296 // Destroy this object.
297
298 // MANIPULATORS
299 SeedGenerator& operator=(const SeedGenerator& rhs) = default;
300 // Assign to this object the value of the specified 'rhs' object, and
301 // return a reference providing modifiable access to this object.
302
303 /// Generate a seed of the specified `seedLength` bytes and store it at
304 /// the specified `seedLocation`. The seed will be generated with bytes
305 /// from the random number generator supplied at construction. All of
306 /// the returned bytes will come from the RNG, meaning if the requested
307 /// seed is larger than the return type of the RNG, the RNG will be
308 /// called multiple times. The behaviour is undefined unless the memory
309 /// at `seedLocation` can store `seedLength` bytes.
310 void generateSeed(char *seedLocation, size_t seedLength);
311};
312
313// ============================================================================
314// INLINE DEFINITIONS
315// ============================================================================
316
317// CREATORS
318template<class RANDOM_NUM_GEN>
319inline
321: RANDOM_NUM_GEN()
322{
323}
324
325template<class RANDOM_NUM_GEN>
326inline
328 const RANDOM_NUM_GEN &randomNumberGenerator)
329: RANDOM_NUM_GEN(randomNumberGenerator)
330{
331}
332
333// MANIPULATORS
334template<class RANDOM_NUM_GEN>
335inline
337 size_t seedLength)
338{
339 BSLS_ASSERT(seedLocation || !seedLength);
340
341 size_t numChunks = seedLength / k_RNGOUTPUTSIZE;
342 size_t remainder = seedLength % k_RNGOUTPUTSIZE;
343
344 for (size_t i = 0; i != numChunks; ++i) {
345 result_type rand = RANDOM_NUM_GEN::operator()();
346 memcpy(seedLocation + i * sizeof(rand), &rand, sizeof(rand));
347 }
348
349 if (remainder) {
350 result_type rand = RANDOM_NUM_GEN::operator()();
351 memcpy(seedLocation + numChunks * sizeof(rand), &rand, remainder);
352 }
353}
354
355} // close package namespace
356
357
358
359#endif
360
361// ----------------------------------------------------------------------------
362// Copyright 2014 Bloomberg Finance L.P.
363//
364// Licensed under the Apache License, Version 2.0 (the "License");
365// you may not use this file except in compliance with the License.
366// You may obtain a copy of the License at
367//
368// http://www.apache.org/licenses/LICENSE-2.0
369//
370// Unless required by applicable law or agreed to in writing, software
371// distributed under the License is distributed on an "AS IS" BASIS,
372// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
373// See the License for the specific language governing permissions and
374// limitations under the License.
375// ----------------------------- END-OF-FILE ----------------------------------
376
377/** @} */
378/** @} */
379/** @} */
Definition bslh_seedgenerator.h:266
SeedGenerator(const SeedGenerator &original)=default
SeedGenerator()
Definition bslh_seedgenerator.h:320
void generateSeed(char *seedLocation, size_t seedLength)
Definition bslh_seedgenerator.h:336
SeedGenerator & operator=(const SeedGenerator &rhs)=default
~SeedGenerator()=default
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bslh_defaulthashalgorithm.h:339