1 // Copyright 2021 The Tint 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 // http://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 #ifndef FUZZERS_RANDOM_GENERATOR_H_ 16 #define FUZZERS_RANDOM_GENERATOR_H_ 17 18 #include <memory> 19 #include <random> 20 #include <vector> 21 22 #include "fuzzers/random_generator_engine.h" 23 24 namespace tint { 25 namespace fuzzers { 26 27 /// Pseudo random generator utility class for fuzzing 28 class RandomGenerator { 29 public: 30 /// @brief Initializes using provided engine 31 /// @param engine - engine implementation to use 32 explicit RandomGenerator(std::unique_ptr<RandomGeneratorEngine> engine); 33 34 /// @brief Creates a MersenneTwisterEngine and initializes using that 35 /// @param seed - seed value to use for engine 36 explicit RandomGenerator(uint64_t seed); 37 38 ~RandomGenerator() = default; 39 RandomGenerator(RandomGenerator&&) = default; 40 41 /// Get uint32_t value from uniform distribution. 42 /// @param lower - lower bound of integer generated 43 /// @param upper - upper bound of integer generated 44 /// @returns i, where lower <= i < upper 45 uint32_t GetUInt32(uint32_t lower, uint32_t upper); 46 47 /// Get uint32_t value from uniform distribution. 48 /// @param bound - Upper bound of integer generated 49 /// @returns i, where 0 <= i < bound 50 uint32_t GetUInt32(uint32_t bound); 51 52 /// Get uint32_t value from uniform distribution. 53 /// @param lower - lower bound of integer generated 54 /// @param upper - upper bound of integer generated 55 /// @returns i, where lower <= i < upper 56 uint64_t GetUInt64(uint64_t lower, uint64_t upper); 57 58 /// Get uint64_t value from uniform distribution. 59 /// @param bound - Upper bound of integer generated 60 /// @returns i, where 0 <= i < bound 61 uint64_t GetUInt64(uint64_t bound); 62 63 /// Get 1 byte of pseudo-random data 64 /// Should be more efficient then calling GetNBytes(1); 65 /// @returns 1-byte of random data 66 uint8_t GetByte(); 67 68 /// Get 4 bytes of pseudo-random data 69 /// Should be more efficient then calling GetNBytes(4); 70 /// @returns 4-bytes of random data 71 uint32_t Get4Bytes(); 72 73 /// Get N bytes of pseudo-random data 74 /// @param dest - memory location to store data 75 /// @param n - number of bytes of data to get 76 void GetNBytes(uint8_t* dest, size_t n); 77 78 /// Get random bool with even odds 79 /// @returns true 50% of the time and false %50 of time. 80 bool GetBool(); 81 82 /// Get random bool with weighted odds 83 /// @param percentage - likelihood of true being returned 84 /// @returns true |percentage|% of the time, and false (100 - |percentage|)% 85 /// of the time. 86 bool GetWeightedBool(uint32_t percentage); 87 88 /// Returns a randomly-chosen element from vector v. 89 /// @param v - the vector from which the random element will be selected. 90 /// @return a random element of vector v. 91 template <typename T> GetRandomElement(const std::vector<T> & v)92 inline T GetRandomElement(const std::vector<T>& v) { 93 return v[GetUInt64(0, v.size())]; 94 } 95 96 /// Calculate a seed value based on a blob of data. 97 /// Currently hashes bytes near the front of the buffer, after skipping N 98 /// bytes. 99 /// @param data - pointer to data to base calculation off of, must be !nullptr 100 /// @param size - number of elements in |data|, must be > 0 101 static uint64_t CalculateSeed(const uint8_t* data, size_t size); 102 103 private: 104 // Disallow copy & assign 105 RandomGenerator(const RandomGenerator&) = delete; 106 RandomGenerator& operator=(const RandomGenerator&) = delete; 107 108 std::unique_ptr<RandomGeneratorEngine> engine_; 109 110 }; // class RandomGenerator 111 112 } // namespace fuzzers 113 } // namespace tint 114 115 #endif // FUZZERS_RANDOM_GENERATOR_H_ 116