random.h (8274B)
1 // Copyright 2017 The Abseil Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 // ----------------------------------------------------------------------------- 16 // File: random.h 17 // ----------------------------------------------------------------------------- 18 // 19 // This header defines the recommended Uniform Random Bit Generator (URBG) 20 // types for use within the Abseil Random library. These types are not 21 // suitable for security-related use-cases, but should suffice for most other 22 // uses of generating random values. 23 // 24 // The Abseil random library provides the following URBG types: 25 // 26 // * BitGen, a good general-purpose bit generator, optimized for generating 27 // random (but not cryptographically secure) values 28 // * InsecureBitGen, a slightly faster, though less random, bit generator, for 29 // cases where the existing BitGen is a drag on performance. 30 31 #ifndef ABSL_RANDOM_RANDOM_H_ 32 #define ABSL_RANDOM_RANDOM_H_ 33 34 #include <cstdint> 35 #include <random> 36 37 #include "absl/base/config.h" 38 #include "absl/random/distributions.h" // IWYU pragma: export 39 #include "absl/random/internal/nonsecure_base.h" 40 #include "absl/random/internal/pcg_engine.h" 41 #include "absl/random/internal/randen_engine.h" 42 #include "absl/random/seed_sequences.h" // IWYU pragma: export 43 44 namespace absl { 45 ABSL_NAMESPACE_BEGIN 46 47 // ----------------------------------------------------------------------------- 48 // absl::BitGen 49 // ----------------------------------------------------------------------------- 50 // 51 // `absl::BitGen` is a general-purpose random bit generator for generating 52 // random values for use within the Abseil random library. Typically, you use a 53 // bit generator in combination with a distribution to provide random values. 54 // 55 // Example: 56 // 57 // // Create an absl::BitGen. There is no need to seed this bit generator. 58 // absl::BitGen gen; 59 // 60 // // Generate an integer value in the closed interval [1,6] 61 // int die_roll = absl::uniform_int_distribution<int>(1, 6)(gen); 62 // 63 // `absl::BitGen` is seeded by default with non-deterministic data to produce 64 // different sequences of random values across different instances, including 65 // different binary invocations. This behavior is different than the standard 66 // library bit generators, which use golden values as their seeds. Default 67 // construction intentionally provides no stability guarantees, to avoid 68 // accidental dependence on such a property. 69 // 70 // `absl::BitGen` may be constructed with an optional seed sequence type, 71 // conforming to [rand.req.seed_seq], which will be mixed with additional 72 // non-deterministic data as detailed below. 73 // 74 // Example: 75 // 76 // // Create an absl::BitGen using an std::seed_seq seed sequence 77 // std::seed_seq seq{1,2,3}; 78 // absl::BitGen gen_with_seed(seq); 79 // 80 // // Generate an integer value in the closed interval [1,6] 81 // int die_roll2 = absl::uniform_int_distribution<int>(1, 6)(gen_with_seed); 82 // 83 // Constructing two `absl::BitGen`s with the same seed sequence in the same 84 // process will produce the same sequence of variates, but need not do so across 85 // multiple processes even if they're executing the same binary. 86 // 87 // `absl::BitGen` meets the requirements of the Uniform Random Bit Generator 88 // (URBG) concept as per the C++17 standard [rand.req.urng] though differs 89 // slightly with [rand.req.eng]. Like its standard library equivalents (e.g. 90 // `std::mersenne_twister_engine`) `absl::BitGen` is not cryptographically 91 // secure. 92 // 93 // This type has been optimized to perform better than Mersenne Twister 94 // (https://en.wikipedia.org/wiki/Mersenne_Twister) and many other complex URBG 95 // types on modern x86, ARM, and PPC architectures. 96 // 97 // This type is thread-compatible, but not thread-safe. 98 class BitGen : private random_internal::NonsecureURBGBase< 99 random_internal::randen_engine<uint64_t>> { 100 using Base = random_internal::NonsecureURBGBase< 101 random_internal::randen_engine<uint64_t>>; 102 103 public: 104 using result_type = typename Base::result_type; 105 106 // BitGen() 107 // BitGen(SeedSequence seed_seq) 108 // 109 // Copy disallowed. 110 // Move allowed. 111 using Base::Base; 112 using Base::operator=; 113 114 // BitGen::min() 115 // 116 // Returns the smallest possible value from this bit generator. 117 using Base::min; 118 119 // BitGen::max() 120 // 121 // Returns the largest possible value from this bit generator. 122 using Base::max; 123 124 // BitGen::discard(num) 125 // 126 // Advances the internal state of this bit generator by `num` times, and 127 // discards the intermediate results. 128 using Base::discard; 129 130 // BitGen::operator()() 131 // 132 // Invoke the URBG, returning a generated value. 133 using Base::operator(); 134 135 using Base::operator==; 136 using Base::operator!=; 137 }; 138 139 // ----------------------------------------------------------------------------- 140 // absl::InsecureBitGen 141 // ----------------------------------------------------------------------------- 142 // 143 // `absl::InsecureBitGen` is an efficient random bit generator for generating 144 // random values, recommended only for performance-sensitive use cases where 145 // `absl::BitGen` is not satisfactory when compute-bounded by bit generation 146 // costs. 147 // 148 // Example: 149 // 150 // // Create an absl::InsecureBitGen 151 // absl::InsecureBitGen gen; 152 // for (size_t i = 0; i < 1000000; i++) { 153 // 154 // // Generate a bunch of random values from some complex distribution 155 // auto my_rnd = some_distribution(gen, 1, 1000); 156 // } 157 // 158 // Like `absl::BitGen`, `absl::InsecureBitGen` is seeded by default with 159 // non-deterministic data to produce different sequences of random values across 160 // different instances, including different binary invocations. (This behavior 161 // is different than the standard library bit generators, which use golden 162 // values as their seeds.) 163 // 164 // `absl::InsecureBitGen` may be constructed with an optional seed sequence 165 // type, conforming to [rand.req.seed_seq], which will be mixed with additional 166 // non-deterministic data, as detailed in the `absl::BitGen` comment. 167 // 168 // `absl::InsecureBitGen` meets the requirements of the Uniform Random Bit 169 // Generator (URBG) concept as per the C++17 standard [rand.req.urng] though 170 // its implementation differs slightly with [rand.req.eng]. Like its standard 171 // library equivalents (e.g. `std::mersenne_twister_engine`) 172 // `absl::InsecureBitGen` is not cryptographically secure. 173 // 174 // Prefer `absl::BitGen` over `absl::InsecureBitGen` as the general type is 175 // often fast enough for the vast majority of applications. However, it is 176 // reasonable to use `absl::InsecureBitGen` in tests or when using a URBG 177 // in small isolated tasks such as in `std::shuffle`. 178 // 179 // This type is thread-compatible, but not thread-safe. 180 class InsecureBitGen : private random_internal::NonsecureURBGBase< 181 random_internal::pcg64_2018_engine> { 182 using Base = 183 random_internal::NonsecureURBGBase<random_internal::pcg64_2018_engine>; 184 185 public: 186 using result_type = typename Base::result_type; 187 188 // InsecureBitGen() 189 // InsecureBitGen(SeedSequence seed_seq) 190 // 191 // Copy disallowed. 192 // Move allowed. 193 using Base::Base; 194 using Base::operator=; 195 196 // InsecureBitGen::min() 197 // 198 // Returns the smallest possible value from this bit generator. 199 using Base::min; 200 201 // InsecureBitGen::max() 202 // 203 // Returns the largest possible value from this bit generator. 204 using Base::max; 205 206 // InsecureBitGen::discard(num) 207 // 208 // Advances the internal state of this bit generator by `num` times, and 209 // discards the intermediate results. 210 using Base::discard; 211 212 // InsecureBitGen::operator()() 213 // 214 // Invoke the URBG, returning a generated value. 215 using Base::operator(); 216 217 using Base::operator==; 218 using Base::operator!=; 219 }; 220 221 ABSL_NAMESPACE_END 222 } // namespace absl 223 224 #endif // ABSL_RANDOM_RANDOM_H_