Enigma  3.2.0
A Simple, Reliable and Efficient Encryption Tool
Random.hpp
Go to the documentation of this file.
1 #pragma once
2 #ifndef ENIGMA_RANDOM_H
3 #define ENIGMA_RANDOM_H
4 
5 #include <Core/Core.hpp>
6 #include <algorithm>
7 #include <random>
8 #include <climits>
9 //#include <execution> // std::for_each(std::execution::par, ...)
10 
12 class Random final {
13  ENIGMA_STATIC_CLASS(Random);
14 
15  public:
22  template<typename T>
23  static typename std::enable_if<std::is_floating_point<T>::value, T>::type
24  Real(const T min, const T max) {
25  ENIGMA_ASSERT(min < max, "min random value should be less than max value");
26  std::uniform_real_distribution<T> dist(min, max);
27  return dist(m_engine);
28  }
29 
36  template<typename T>
37  static typename std::enable_if<std::is_integral<T>::value && !std::is_same<T, bool>::value, T>::type
38  Int(const T min, const T max) {
39  ENIGMA_ASSERT(min < max, "min random value should be less than max value");
40  std::uniform_int_distribution<T> dist(min, max);
41  return dist(m_engine);
42  }
43 
49  static bool Bool(const double p = 0.5) {
50  std::bernoulli_distribution dist(p);
51  return !!dist(m_engine);
52  }
53 
54 
59  static std::string Str(const std::size_t length) noexcept {
60  static std::random_device seed{};
61  static std::default_random_engine engine{seed()};
62  static std::uniform_int_distribution<short> choice(0, 2);
63  static std::uniform_int_distribution<int> lowercaseAlpha('a', 'z');
64  static std::uniform_int_distribution<int> uppercaseAlpha('A', 'Z');
65  static std::uniform_int_distribution<int> digits('0', '9');
66 
67  std::string str(length, '\000');
68  for (char& c: str) {
69  switch (choice(engine)) {
70  case 0: // a-z
71  c = lowercaseAlpha(engine);
72  break;
73  case 1: // A-Z
74  c = uppercaseAlpha(engine);
75  break;
76  case 2: // 0-9
77  c = digits(engine);
78  break;
79  default:
80  break;
81  }
82  }
83  return str;
84  }
85 
90  static std::vector<byte> Bytes(const std::size_t length) noexcept {
91  std::vector<byte> bytes(length);
92 #ifndef _MSC_VER
93  using random_bytes_engine = std::independent_bits_engine<std::default_random_engine, CHAR_BIT, byte>;
94  static random_bytes_engine gen{m_engine};
95  std::generate(bytes.begin(), bytes.end(), std::ref(gen));
96 #else
97  // MSVC's std::independent_bits_engine doesn't take std::uint8_t
98  std::uniform_int_distribution<std::uint16_t> dist{static_cast<std::uint16_t>(std::numeric_limits<byte>::min()), static_cast<std::uint16_t>(std::numeric_limits<byte>::max())};
99  std::generate(bytes.begin(), bytes.end(), [&]() -> byte {
100  return dist(m_engine);
101  });
102 #endif
103  return bytes;
104  }
105 
106 
108  static void Reseed() {
109  m_engine.seed(m_seed());
110  }
111 
112  private:
113  inline static std::random_device m_seed{};
114  inline static std::default_random_engine m_engine{m_seed()};
115 };
117 
118 #endif // !ENIGMA_RANDOM_H
#define NS_ENIGMA_BEGIN
Enable/Disable Assertions.
Definition: Macros.hpp:13
#define NS_ENIGMA_END
Definition: Macros.hpp:14
#define ENIGMA_ASSERT(x,...)
Asserts.
Definition: Macros.hpp:38
static bool Bool(const double p=0.5)
Generates a random boolean value.
Definition: Random.hpp:49
static std::vector< byte > Bytes(const std::size_t length) noexcept
Generates a random vector of bytes.
Definition: Random.hpp:90
static std::enable_if< std::is_integral< T >::value &&!std::is_same< T, bool >::value, T >::type Int(const T min, const T max)
Generates a random integer between a range.
Definition: Random.hpp:38
static std::enable_if< std::is_floating_point< T >::value, T >::type Real(const T min, const T max)
Generates a random real between a range.
Definition: Random.hpp:24
static void Reseed()
Definition: Random.hpp:108
static std::string Str(const std::size_t length) noexcept
Generates a random string.
Definition: Random.hpp:59