1*9356374aSAndroid Build Coastguard Worker // Copyright 2017 The Abseil Authors.
2*9356374aSAndroid Build Coastguard Worker //
3*9356374aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*9356374aSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*9356374aSAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*9356374aSAndroid Build Coastguard Worker //
7*9356374aSAndroid Build Coastguard Worker // https://www.apache.org/licenses/LICENSE-2.0
8*9356374aSAndroid Build Coastguard Worker //
9*9356374aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*9356374aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*9356374aSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*9356374aSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*9356374aSAndroid Build Coastguard Worker // limitations under the License.
14*9356374aSAndroid Build Coastguard Worker //
15*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
16*9356374aSAndroid Build Coastguard Worker // File: seed_sequences.h
17*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
18*9356374aSAndroid Build Coastguard Worker //
19*9356374aSAndroid Build Coastguard Worker // This header contains utilities for creating and working with seed sequences
20*9356374aSAndroid Build Coastguard Worker // conforming to [rand.req.seedseq]. In general, direct construction of seed
21*9356374aSAndroid Build Coastguard Worker // sequences is discouraged, but use-cases for construction of identical bit
22*9356374aSAndroid Build Coastguard Worker // generators (using the same seed sequence) may be helpful (e.g. replaying a
23*9356374aSAndroid Build Coastguard Worker // simulation whose state is derived from variates of a bit generator).
24*9356374aSAndroid Build Coastguard Worker
25*9356374aSAndroid Build Coastguard Worker #ifndef ABSL_RANDOM_SEED_SEQUENCES_H_
26*9356374aSAndroid Build Coastguard Worker #define ABSL_RANDOM_SEED_SEQUENCES_H_
27*9356374aSAndroid Build Coastguard Worker
28*9356374aSAndroid Build Coastguard Worker #include <iterator>
29*9356374aSAndroid Build Coastguard Worker #include <random>
30*9356374aSAndroid Build Coastguard Worker
31*9356374aSAndroid Build Coastguard Worker #include "absl/base/config.h"
32*9356374aSAndroid Build Coastguard Worker #include "absl/base/nullability.h"
33*9356374aSAndroid Build Coastguard Worker #include "absl/random/internal/salted_seed_seq.h"
34*9356374aSAndroid Build Coastguard Worker #include "absl/random/internal/seed_material.h"
35*9356374aSAndroid Build Coastguard Worker #include "absl/random/seed_gen_exception.h"
36*9356374aSAndroid Build Coastguard Worker #include "absl/strings/string_view.h"
37*9356374aSAndroid Build Coastguard Worker #include "absl/types/span.h"
38*9356374aSAndroid Build Coastguard Worker
39*9356374aSAndroid Build Coastguard Worker namespace absl {
40*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_BEGIN
41*9356374aSAndroid Build Coastguard Worker
42*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
43*9356374aSAndroid Build Coastguard Worker // absl::SeedSeq
44*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
45*9356374aSAndroid Build Coastguard Worker //
46*9356374aSAndroid Build Coastguard Worker // `absl::SeedSeq` constructs a seed sequence according to [rand.req.seedseq]
47*9356374aSAndroid Build Coastguard Worker // for use within bit generators. `absl::SeedSeq`, unlike `std::seed_seq`
48*9356374aSAndroid Build Coastguard Worker // additionally salts the generated seeds with extra implementation-defined
49*9356374aSAndroid Build Coastguard Worker // entropy. For that reason, you can use `absl::SeedSeq` in combination with
50*9356374aSAndroid Build Coastguard Worker // standard library bit generators (e.g. `std::mt19937`) to introduce
51*9356374aSAndroid Build Coastguard Worker // non-determinism in your seeds.
52*9356374aSAndroid Build Coastguard Worker //
53*9356374aSAndroid Build Coastguard Worker // Example:
54*9356374aSAndroid Build Coastguard Worker //
55*9356374aSAndroid Build Coastguard Worker // absl::SeedSeq my_seed_seq({a, b, c});
56*9356374aSAndroid Build Coastguard Worker // std::mt19937 my_bitgen(my_seed_seq);
57*9356374aSAndroid Build Coastguard Worker //
58*9356374aSAndroid Build Coastguard Worker using SeedSeq = random_internal::SaltedSeedSeq<std::seed_seq>;
59*9356374aSAndroid Build Coastguard Worker
60*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
61*9356374aSAndroid Build Coastguard Worker // absl::CreateSeedSeqFrom(bitgen*)
62*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
63*9356374aSAndroid Build Coastguard Worker //
64*9356374aSAndroid Build Coastguard Worker // Constructs a seed sequence conforming to [rand.req.seedseq] using variates
65*9356374aSAndroid Build Coastguard Worker // produced by a provided bit generator.
66*9356374aSAndroid Build Coastguard Worker //
67*9356374aSAndroid Build Coastguard Worker // You should generally avoid direct construction of seed sequences, but
68*9356374aSAndroid Build Coastguard Worker // use-cases for reuse of a seed sequence to construct identical bit generators
69*9356374aSAndroid Build Coastguard Worker // may be helpful (eg. replaying a simulation whose state is derived from bit
70*9356374aSAndroid Build Coastguard Worker // generator values).
71*9356374aSAndroid Build Coastguard Worker //
72*9356374aSAndroid Build Coastguard Worker // If bitgen == nullptr, then behavior is undefined.
73*9356374aSAndroid Build Coastguard Worker //
74*9356374aSAndroid Build Coastguard Worker // Example:
75*9356374aSAndroid Build Coastguard Worker //
76*9356374aSAndroid Build Coastguard Worker // absl::BitGen my_bitgen;
77*9356374aSAndroid Build Coastguard Worker // auto seed_seq = absl::CreateSeedSeqFrom(&my_bitgen);
78*9356374aSAndroid Build Coastguard Worker // absl::BitGen new_engine(seed_seq); // derived from my_bitgen, but not
79*9356374aSAndroid Build Coastguard Worker // // correlated.
80*9356374aSAndroid Build Coastguard Worker //
81*9356374aSAndroid Build Coastguard Worker template <typename URBG>
CreateSeedSeqFrom(URBG * urbg)82*9356374aSAndroid Build Coastguard Worker SeedSeq CreateSeedSeqFrom(URBG* urbg) {
83*9356374aSAndroid Build Coastguard Worker SeedSeq::result_type
84*9356374aSAndroid Build Coastguard Worker seed_material[random_internal::kEntropyBlocksNeeded];
85*9356374aSAndroid Build Coastguard Worker
86*9356374aSAndroid Build Coastguard Worker if (!random_internal::ReadSeedMaterialFromURBG(
87*9356374aSAndroid Build Coastguard Worker urbg, absl::MakeSpan(seed_material))) {
88*9356374aSAndroid Build Coastguard Worker random_internal::ThrowSeedGenException();
89*9356374aSAndroid Build Coastguard Worker }
90*9356374aSAndroid Build Coastguard Worker return SeedSeq(std::begin(seed_material), std::end(seed_material));
91*9356374aSAndroid Build Coastguard Worker }
92*9356374aSAndroid Build Coastguard Worker
93*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
94*9356374aSAndroid Build Coastguard Worker // absl::MakeSeedSeq()
95*9356374aSAndroid Build Coastguard Worker // -----------------------------------------------------------------------------
96*9356374aSAndroid Build Coastguard Worker //
97*9356374aSAndroid Build Coastguard Worker // Constructs an `absl::SeedSeq` salting the generated values using
98*9356374aSAndroid Build Coastguard Worker // implementation-defined entropy. The returned sequence can be used to create
99*9356374aSAndroid Build Coastguard Worker // equivalent bit generators correlated using this sequence.
100*9356374aSAndroid Build Coastguard Worker //
101*9356374aSAndroid Build Coastguard Worker // Example:
102*9356374aSAndroid Build Coastguard Worker //
103*9356374aSAndroid Build Coastguard Worker // auto my_seed_seq = absl::MakeSeedSeq();
104*9356374aSAndroid Build Coastguard Worker // std::mt19937 rng1(my_seed_seq);
105*9356374aSAndroid Build Coastguard Worker // std::mt19937 rng2(my_seed_seq);
106*9356374aSAndroid Build Coastguard Worker // EXPECT_EQ(rng1(), rng2());
107*9356374aSAndroid Build Coastguard Worker //
108*9356374aSAndroid Build Coastguard Worker SeedSeq MakeSeedSeq();
109*9356374aSAndroid Build Coastguard Worker
110*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_END
111*9356374aSAndroid Build Coastguard Worker } // namespace absl
112*9356374aSAndroid Build Coastguard Worker
113*9356374aSAndroid Build Coastguard Worker #endif // ABSL_RANDOM_SEED_SEQUENCES_H_
114