81# include <type_traits>
86# include <string_view>
87# include <unordered_set>
93# if defined(_MSC_VER) && (defined(__x86_64__) || defined(_M_X64))
94# include <immintrin.h>
97# if defined(_WIN32) && __has_include(<bcrypt.h>)
100# ifndef WIN32_LEAN_AND_MEAN
101# define WIN32_LEAN_AND_MEAN
108# pragma comment(lib, "bcrypt.lib")
110# if(defined(__MINGW32__) || defined(__MINGW64__)) && !defined(RANDX_SUPPRESS_LINK_HINT)
111# pragma message("RandX: MinGW 需手动链接 bcrypt(编译命令添加 -lbcrypt)")
113# elif defined(__linux__) && __has_include(<sys/random.h>)
114# include <sys/random.h>
116# elif defined(__APPLE__) && __has_include(<Security/Security.h>)
117# include <Security/Security.h>
121# if __has_cpp_attribute(nodiscard) >= 201907L
122# define RANDX_NODISCARD_CXX20 [[nodiscard]]
124# define RANDX_NODISCARD_CXX20
130 inline constexpr std::uint64_t
DefaultSeed = 1234567890ULL;
134 template <
class U
int32, std::enable_if_t<std::is_same_v<U
int32, std::u
int32_t>>* =
nullptr>
140 template <
class U
int64, std::enable_if_t<std::is_same_v<U
int64, std::u
int64_t>>* =
nullptr>
169 template <
class SeedSeq,
170 std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>,
SplitMix64>>* =
nullptr>
180 constexpr
void discard(
unsigned long long n) noexcept;
185 template <std::
size_t N>
213 return (lhs.m_state == rhs.m_state);
219 return (lhs.m_state != rhs.m_state);
235 class Xoshiro256StarStar
249 template <
class SeedSeq,
250 std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>,
Xoshiro256StarStar>>* =
nullptr>
265 constexpr
void discard(
unsigned long long n) noexcept;
270 constexpr
void jump() noexcept;
301 return (lhs.m_state == rhs.m_state);
307 return (lhs.m_state != rhs.m_state);
323 class Xoroshiro128StarStar
337 template <
class SeedSeq,
353 constexpr
void discard(
unsigned long long n) noexcept;
358 constexpr
void jump() noexcept;
389 return (lhs.m_state == rhs.m_state);
395 return (lhs.m_state != rhs.m_state);
411 class Xoshiro128StarStar
425 template <
class SeedSeq,
426 std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>,
Xoshiro128StarStar>>* =
nullptr>
441 constexpr
void discard(
unsigned long long n) noexcept;
446 constexpr
void jump() noexcept;
477 return (lhs.m_state == rhs.m_state);
483 return (lhs.m_state != rhs.m_state);
499 class Xoroshiro64StarStar
513 template <
class SeedSeq,
529 constexpr
void discard(
unsigned long long n) noexcept;
555 return (lhs.m_state == rhs.m_state);
561 return (lhs.m_state != rhs.m_state);
590 template <
class SeedSeq,
591 std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>,
SFC64>>* =
nullptr>
593 explicit constexpr SFC64(SeedSeq& seq);
606 constexpr
void discard(
unsigned long long n) noexcept;
630 friend
bool operator ==(const
SFC64& lhs, const
SFC64& rhs) noexcept
632 return (lhs.serialize() == rhs.serialize());
638 return (lhs.serialize() != rhs.serialize());
646 std::uint64_t m_counter;
671 template <
class SeedSeq,
672 std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>,
RomuDuoJr>>* =
nullptr>
687 constexpr
void discard(
unsigned long long n) noexcept;
713 return (lhs.serialize() == rhs.serialize());
719 return (lhs.serialize() != rhs.serialize());
768 ChaCha20(const std::uint8_t* key, std::
size_t keyLen,
769 const std::uint8_t* nonce, std::
size_t nonceLen,
770 std::uint32_t counter = 0);
798 std::array<std::uint32_t, 12> m_state;
799 std::array<std::uint8_t, 64> m_buffer;
800 std::size_t m_bufferPos;
801 std::uint64_t m_bytesSinceReseed;
803 void generateBlock();
804 void reseedIfNecessary();
812 template <
class U
int32, std::enable_if_t<std::is_same_v<U
int32, std::u
int32_t>>*>
815 return (i >> 8) * 0x1.0p-24f;
818 template <
class U
int64, std::enable_if_t<std::is_same_v<U
int64, std::u
int64_t>>*>
821 return (i >> 11) * 0x1.0p-53;
827 static constexpr std::uint64_t
RotL(
const std::uint64_t x,
const int s)
noexcept
829 const int count = s & 63;
830 return count == 0 ? x : ((x << count) | (x >> (64 - count)));
834 static constexpr std::uint32_t
RotL(
const std::uint32_t x,
const int s)
noexcept
836 const int count = s & 31;
837 return count == 0 ? x : ((x << count) | (x >> (32 - count)));
843 volatile auto* p =
static_cast<volatile std::uint8_t*
>(ptr);
844 while (len--) *p++ = 0;
848 template <std::
size_t N>
850 static constexpr bool IsAllZero(
const std::array<std::uint64_t, N>& state)
noexcept
852 for (
const auto& s : state) {
if (s != 0)
return false; }
856 template <std::
size_t N>
858 static constexpr bool IsAllZero(
const std::array<std::uint32_t, N>& state)
noexcept
860 for (
const auto& s : state) {
if (s != 0)
return false; }
868#if defined(__x86_64__) || defined(_M_X64)
869 #if defined(__RDRND__)
870 unsigned long long result;
871 if (__builtin_ia32_rdrand64_step(&result))
876 #elif defined(_MSC_VER)
877 unsigned long long result;
878 if (_rdrand64_step(&result))
896 if (n == 0)
return true;
897 auto* p =
static_cast<std::uint8_t*
>(buf);
899# if defined(_WIN32) && __has_include(<bcrypt.h>)
902 std::size_t filled = 0;
905 const ULONG chunkSize =
static_cast<ULONG
>((std::min)(n - filled,
static_cast<std::size_t
>((std::numeric_limits<ULONG>::max)())));
906 if (::BCryptGenRandom(
nullptr, p + filled, chunkSize, BCRYPT_USE_SYSTEM_PREFERRED_RNG) < 0)
914# elif defined(__linux__) && __has_include(<sys/random.h>)
916 std::size_t filled = 0;
919 const ssize_t ret = ::getrandom(p + filled, n - filled, 0);
922 if (errno == EINTR)
continue;
925 if (ret == 0)
return false;
926 filled +=
static_cast<std::size_t
>(ret);
930# elif defined(__APPLE__) && __has_include(<Security/Security.h>)
932 return (::SecRandomCopyBytes(kSecRandomDefault, n, p) == errSecSuccess);
947# if (defined(_WIN32) && __has_include(<bcrypt.h>)) || (defined(__linux__) && __has_include(<sys/random.h>)) || (defined(__APPLE__) && __has_include(<Security/Security.h>))
957 0x61707865u, 0x3320646eu, 0x79622d32u, 0x6b206574u
965 std::uint32_t& c, std::uint32_t& d)
noexcept
967 a += b; d ^= a; d =
RotL(d, 16);
968 c += d; b ^= c; b =
RotL(b, 12);
969 a += b; d ^= a; d =
RotL(d, 8);
970 c += d; b ^= c; b =
RotL(b, 7);
981 template <
class SeedSeq, std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>, SplitMix64>>*>
984 std::array<std::uint32_t, 2> seeds;
985 seq.generate(seeds.begin(), seeds.end());
986 m_state = (
static_cast<std::uint64_t
>(seeds[0]) << 32) | seeds[1];
991 std::uint64_t z = (m_state += 0x9e3779b97f4a7c15);
992 z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
993 z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
994 return z ^ (z >> 31);
997 template <std::
size_t N>
1000 std::array<std::uint64_t, N> seeds = {};
1002 for (
auto& seed : seeds)
1012 return std::numeric_limits<result_type>::lowest();
1017 return std::numeric_limits<result_type>::max();
1032 for (
unsigned long long i = 0; i < n; ++i) { operator()(); }
1045 template <
class SeedSeq, std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>, Xoshiro256StarStar>>*>
1048 std::array<std::uint32_t, 8> seeds;
1049 seq.generate(seeds.begin(), seeds.end());
1050 for (
int i = 0; i < 4; ++i)
1051 m_state[i] = (
static_cast<std::uint64_t
>(seeds[2*i]) << 32) | seeds[2*i+1];
1063 const std::uint64_t result =
detail::RotL(m_state[1] * 5, 7) * 9;
1064 const std::uint64_t t = m_state[1] << 17;
1065 m_state[2] ^= m_state[0];
1066 m_state[3] ^= m_state[1];
1067 m_state[1] ^= m_state[2];
1068 m_state[0] ^= m_state[3];
1076 constexpr std::uint64_t JUMP[] = { 0x180ec6d33cfd0aba, 0xd5a61266f0c9392c, 0xa9582618e03fc9aa, 0x39abdc4529b1661c };
1078 std::uint64_t s0 = 0;
1079 std::uint64_t s1 = 0;
1080 std::uint64_t s2 = 0;
1081 std::uint64_t s3 = 0;
1083 for (std::uint64_t j : JUMP)
1085 for (
int b = 0; b < 64; ++b)
1087 if (j & UINT64_C(1) << b)
1106 constexpr std::uint64_t LONG_JUMP[] = { 0x76e15d3efefdcbbf, 0xc5004e441c522fb3, 0x77710069854ee241, 0x39109bb02acbe635 };
1108 std::uint64_t s0 = 0;
1109 std::uint64_t s1 = 0;
1110 std::uint64_t s2 = 0;
1111 std::uint64_t s3 = 0;
1113 for (std::uint64_t j : LONG_JUMP)
1115 for (
int b = 0; b < 64; ++b)
1117 if (j & UINT64_C(1) << b)
1136 return std::numeric_limits<result_type>::lowest();
1141 return std::numeric_limits<result_type>::max();
1157 for (
unsigned long long i = 0; i < n; ++i) { operator()(); }
1170 template <
class SeedSeq, std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>, Xoroshiro128StarStar>>*>
1173 std::array<std::uint32_t, 4> seeds;
1174 seq.generate(seeds.begin(), seeds.end());
1175 m_state[0] = (
static_cast<std::uint64_t
>(seeds[0]) << 32) | seeds[1];
1176 m_state[1] = (
static_cast<std::uint64_t
>(seeds[2]) << 32) | seeds[3];
1188 const std::uint64_t s0 = m_state[0];
1189 std::uint64_t s1 = m_state[1];
1190 const std::uint64_t result =
detail::RotL(s0 * 5, 7) * 9;
1199 constexpr std::uint64_t JUMP[] = { 0xdf900294d8f554a5, 0x170865df4b3201fc };
1201 std::uint64_t s0 = 0;
1202 std::uint64_t s1 = 0;
1204 for (std::uint64_t j : JUMP)
1206 for (
int b = 0; b < 64; ++b)
1208 if (j & UINT64_C(1) << b)
1223 constexpr std::uint64_t LONG_JUMP[] = { 0xd2a98b26625eee7b, 0xdddf9b1090aa7ac1 };
1225 std::uint64_t s0 = 0;
1226 std::uint64_t s1 = 0;
1228 for (std::uint64_t j : LONG_JUMP)
1230 for (
int b = 0; b < 64; ++b)
1232 if (j & UINT64_C(1) << b)
1247 return std::numeric_limits<result_type>::lowest();
1252 return std::numeric_limits<result_type>::max();
1268 for (
unsigned long long i = 0; i < n; ++i) { operator()(); }
1280 for (
auto& state : m_state)
1282 state =
static_cast<std::uint32_t
>(splitmix());
1287 template <
class SeedSeq, std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>, Xoshiro128StarStar>>*>
1290 std::array<std::uint32_t, 4> seeds;
1291 seq.generate(seeds.begin(), seeds.end());
1304 const std::uint32_t result =
detail::RotL(m_state[1] * 5, 7) * 9;
1305 const std::uint32_t t = m_state[1] << 9;
1306 m_state[2] ^= m_state[0];
1307 m_state[3] ^= m_state[1];
1308 m_state[1] ^= m_state[2];
1309 m_state[0] ^= m_state[3];
1317 constexpr std::uint32_t JUMP[] = { 0x8764000b, 0xf542d2d3, 0x6fa035c3, 0x77f2db5b };
1319 std::uint32_t s0 = 0;
1320 std::uint32_t s1 = 0;
1321 std::uint32_t s2 = 0;
1322 std::uint32_t s3 = 0;
1324 for (std::uint32_t j : JUMP)
1326 for (
int b = 0; b < 32; ++b)
1328 if (j & UINT32_C(1) << b)
1347 constexpr std::uint32_t LONG_JUMP[] = { 0xb523952e, 0x0b6f099f, 0xccf5a0ef, 0x1c580662 };
1349 std::uint32_t s0 = 0;
1350 std::uint32_t s1 = 0;
1351 std::uint32_t s2 = 0;
1352 std::uint32_t s3 = 0;
1354 for (std::uint32_t j : LONG_JUMP)
1356 for (
int b = 0; b < 32; ++b)
1358 if (j & UINT32_C(1) << b)
1377 return std::numeric_limits<result_type>::lowest();
1382 return std::numeric_limits<result_type>::max();
1398 for (
unsigned long long i = 0; i < n; ++i) { operator()(); }
1410 for (
auto& state : m_state)
1412 state =
static_cast<std::uint32_t
>(splitmix());
1417 template <
class SeedSeq, std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>, Xoroshiro64StarStar>>*>
1420 std::array<std::uint32_t, 2> seeds;
1421 seq.generate(seeds.begin(), seeds.end());
1434 const std::uint32_t s0 = m_state[0];
1435 std::uint32_t s1 = m_state[1];
1437 const std::uint32_t result =
detail::RotL(s0 * 0x9E3779BB, 5) * 5;
1448 return std::numeric_limits<result_type>::lowest();
1453 return std::numeric_limits<result_type>::max();
1469 for (
unsigned long long i = 0; i < n; ++i) { operator()(); }
1476 inline constexpr SFC64::SFC64(
const std::uint64_t seed) noexcept
1477 : m_a(0), m_b(0), m_c(0), m_counter(1)
1484 for (
int i = 0; i < 12; ++i) { operator()(); }
1487 template <
class SeedSeq, std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>, SFC64>>*>
1491 std::array<std::uint32_t, 8> seeds;
1492 seq.generate(seeds.begin(), seeds.end());
1493 m_a = (
static_cast<std::uint64_t
>(seeds[0]) << 32) | seeds[1];
1494 m_b = (
static_cast<std::uint64_t
>(seeds[2]) << 32) | seeds[3];
1495 m_c = (
static_cast<std::uint64_t
>(seeds[4]) << 32) | seeds[5];
1497 if ((m_a | m_b | m_c) == 0) m_a = 0x9E3779B97F4A7C15ULL;
1499 for (
int i = 0; i < 12; ++i) {
operator()(); }
1502 inline constexpr SFC64::SFC64(
const state_type state) noexcept
1503 : m_a(state[0]), m_b(state[1]), m_c(state[2]), m_counter(state[3]) {}
1507 const std::uint64_t tmp = m_a + m_b + m_counter++;
1508 m_a = m_b ^ (m_b >> 11);
1509 m_b = m_c + (m_c << 3);
1516 return std::numeric_limits<result_type>::lowest();
1521 return std::numeric_limits<result_type>::max();
1526 return { m_a, m_b, m_c, m_counter };
1534 m_counter = state[3];
1537 inline constexpr void SFC64::discard(
const unsigned long long n)
noexcept
1539 for (
unsigned long long i = 0; i < n; ++i) { operator()(); }
1553 if (m_x == 0 && m_y == 0) { m_x = 1; }
1556 template <
class SeedSeq, std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>, RomuDuoJr>>*>
1559 std::array<std::uint32_t, 4> seeds;
1560 seq.generate(seeds.begin(), seeds.end());
1561 m_x = (
static_cast<std::uint64_t
>(seeds[0]) << 32) | seeds[1];
1562 m_y = (
static_cast<std::uint64_t
>(seeds[2]) << 32) | seeds[3];
1563 if (m_x == 0 && m_y == 0) m_x = 1;
1567 : m_x(state[0]), m_y(state[1])
1569 assert(!(m_x == 0 && m_y == 0) &&
"全零状态是吸收态,禁止使用");
1574 const std::uint64_t xp = m_x;
1575 m_x = 15241094284759029579ULL * m_y;
1582 return std::numeric_limits<result_type>::lowest();
1587 return std::numeric_limits<result_type>::max();
1592 return { m_x, m_y };
1597 assert(!(state[0] == 0 && state[1] == 0) &&
"全零状态是吸收态,禁止使用");
1604 for (
unsigned long long i = 0; i < n; ++i) { operator()(); }
1617 template <
class Engine,
class =
void>
1619 template <
class Engine>
1620 struct HasJump<Engine, std::void_t<decltype(std::declval<Engine&>().jump())>> : std::true_type {};
1628 std::is_same_v<T, char>
1629 || std::is_same_v<T, wchar_t>
1630 || std::is_same_v<T, char16_t>
1631 || std::is_same_v<T, char32_t>
1632# if defined(__cpp_char8_t) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
1633 || std::is_same_v<T, char8_t>
1641 template <
class It,
class =
void>
1646 typename std::iterator_traits<It>::iterator_category>>
1647 : std::is_base_of<std::random_access_iterator_tag,
1648 typename std::iterator_traits<It>::iterator_category> {};
1651 template <
class It,
class =
void>
1656 typename std::iterator_traits<It>::iterator_category>>
1657 : std::is_base_of<std::input_iterator_tag,
1658 typename std::iterator_traits<It>::iterator_category> {};
1669 template <
class C,
class =
void>
1674 decltype(std::begin(std::declval<C&>())),
1675 decltype(std::end(std::declval<C&>()))>>
1682 template <
class Engine>
1686 if (
sizeof(
typename Engine::result_type) >= 8)
1688 return static_cast<std::uint64_t
>(engine());
1690 const std::uint64_t lo =
static_cast<std::uint64_t
>(engine());
1691 const std::uint64_t hi =
static_cast<std::uint64_t
>(engine());
1692 return (hi << 32) | lo;
1696 template <
class It,
class T,
class =
void>
1699 template <
class It,
class T>
1701 decltype(*std::declval<It&>() = std::declval<T>())
1702 >> : std::bool_constant<
1703 std::is_integral_v<T> || std::is_floating_point_v<T>
1706 template <
class It,
class T>
1710 template <
class S,
class =
void>
1715 decltype(std::declval<const S&>().size()),
1716 decltype(std::declval<S&>()[std::size_t{}]),
1717 typename S::value_type
1719 decltype(std::declval<const S&>().size()),
1726 template <
class E,
class =
void>
1731 decltype(std::declval<const E&>().serialize()),
1732 decltype(std::declval<E&>().deserialize(
1733 std::declval<typename E::state_type>())),
1734 typename E::state_type
1735 >> : std::bool_constant<
1737 decltype(std::declval<const E&>().serialize()),
1738 typename E::state_type>
1739 && is_indexable_state_v<typename E::state_type>
1746 template <class Engine, std::enable_if_t<detail::HasJump<Engine>::value>* =
nullptr>
1751 for (std::uint64_t i = 0; i < streamId; ++i)
1771 std::random_device rd;
1774 return (
static_cast<std::uint64_t
>(rd()) << 32) | rd();
1779 return static_cast<std::uint64_t
>(std::chrono::system_clock::now().time_since_epoch().count());
1802 throw std::runtime_error(
"SecureRandomBytes: OS entropy source failed");
1838 : m_state(other.m_state),
1839 m_buffer(other.m_buffer),
1840 m_bufferPos(other.m_bufferPos),
1841 m_bytesSinceReseed(other.m_bytesSinceReseed)
1845 other.m_bufferPos = 64;
1846 other.m_bytesSinceReseed = 0;
1856 m_state = other.m_state;
1857 m_buffer = other.m_buffer;
1858 m_bufferPos = other.m_bufferPos;
1859 m_bytesSinceReseed = other.m_bytesSinceReseed;
1863 other.m_bufferPos = 64;
1864 other.m_bytesSinceReseed = 0;
1877 : m_state{}, m_buffer{}, m_bufferPos(64), m_bytesSinceReseed(0)
1884 inline ChaCha20::ChaCha20(
const std::uint64_t seed)
1885 : m_state{}, m_buffer{}, m_bufferPos(64), m_bytesSinceReseed(0)
1889 for (
int i = 0; i < 4; ++i)
1891 const std::uint64_t v = sm();
1892 m_state[i * 2] =
static_cast<std::uint32_t
>(v);
1893 m_state[i * 2 + 1] =
static_cast<std::uint32_t
>(v >> 32);
1897 const std::uint64_t v5 = sm();
1898 m_state[9] =
static_cast<std::uint32_t
>(v5);
1899 m_state[10] =
static_cast<std::uint32_t
>(v5 >> 32);
1901 m_state[11] =
static_cast<std::uint32_t
>(sm());
1906 inline ChaCha20::ChaCha20(
const std::uint8_t* key, std::size_t keyLen,
1907 const std::uint8_t* nonce, std::size_t nonceLen,
1908 const std::uint32_t counter)
1909 : m_state{}, m_buffer{}, m_bufferPos(64), m_bytesSinceReseed(0)
1912 throw std::invalid_argument(
"ChaCha20: key must be 32 bytes");
1914 throw std::invalid_argument(
"ChaCha20: nonce must be 12 bytes");
1916 for (
int i = 0; i < 8; ++i)
1918 m_state[i] =
static_cast<std::uint32_t
>(key[i * 4])
1919 | (
static_cast<std::uint32_t
>(key[i * 4 + 1]) << 8)
1920 | (
static_cast<std::uint32_t
>(key[i * 4 + 2]) << 16)
1921 | (
static_cast<std::uint32_t
>(key[i * 4 + 3]) << 24);
1924 for (
int i = 0; i < 3; ++i)
1926 m_state[9 + i] =
static_cast<std::uint32_t
>(nonce[i * 4])
1927 | (
static_cast<std::uint32_t
>(nonce[i * 4 + 1]) << 8)
1928 | (
static_cast<std::uint32_t
>(nonce[i * 4 + 2]) << 16)
1929 | (
static_cast<std::uint32_t
>(nonce[i * 4 + 3]) << 24);
1931 m_state[8] = counter;
1935 inline void ChaCha20::generateBlock()
1938 std::array<std::uint32_t, 16> state{};
1939 state[0] = detail::ChaCha20Constants[0];
1940 state[1] = detail::ChaCha20Constants[1];
1941 state[2] = detail::ChaCha20Constants[2];
1942 state[3] = detail::ChaCha20Constants[3];
1943 for (
int i = 0; i < 8; ++i) state[4 + i] = m_state[i];
1944 state[12] = m_state[8];
1945 state[13] = m_state[9];
1946 state[14] = m_state[10];
1947 state[15] = m_state[11];
1949 std::array<std::uint32_t, 16> working = state;
1952 for (
int i = 0; i < 10; ++i)
1955 detail::ChaCha20QuarterRound(working[0], working[4], working[8], working[12]);
1956 detail::ChaCha20QuarterRound(working[1], working[5], working[9], working[13]);
1957 detail::ChaCha20QuarterRound(working[2], working[6], working[10], working[14]);
1958 detail::ChaCha20QuarterRound(working[3], working[7], working[11], working[15]);
1960 detail::ChaCha20QuarterRound(working[0], working[5], working[10], working[15]);
1961 detail::ChaCha20QuarterRound(working[1], working[6], working[11], working[12]);
1962 detail::ChaCha20QuarterRound(working[2], working[7], working[8], working[13]);
1963 detail::ChaCha20QuarterRound(working[3], working[4], working[9], working[14]);
1967 for (
int i = 0; i < 16; ++i)
1969 const std::uint32_t v = working[i] + state[i];
1970 m_buffer[i * 4 + 0] =
static_cast<std::uint8_t
>(v);
1971 m_buffer[i * 4 + 1] =
static_cast<std::uint8_t
>(v >> 8);
1972 m_buffer[i * 4 + 2] =
static_cast<std::uint8_t
>(v >> 16);
1973 m_buffer[i * 4 + 3] =
static_cast<std::uint8_t
>(v >> 24);
1976 if (m_state[8] == 0xFFFFFFFFU)
1978 throw std::overflow_error(
"ChaCha20: 32-bit block counter overflow");
1985 inline void ChaCha20::reseedIfNecessary()
1987 if (m_bytesSinceReseed >= detail::ChaCha20ReseedThreshold)
1992 inline void ChaCha20::reseed()
1994 std::array<std::uint8_t, 44> seed;
1997 for (
int i = 0; i < 8; ++i)
1999 m_state[i] =
static_cast<std::uint32_t
>(seed[i * 4])
2000 | (
static_cast<std::uint32_t
>(seed[i * 4 + 1]) << 8)
2001 | (
static_cast<std::uint32_t
>(seed[i * 4 + 2]) << 16)
2002 | (
static_cast<std::uint32_t
>(seed[i * 4 + 3]) << 24);
2005 for (
int i = 0; i < 3; ++i)
2007 m_state[9 + i] =
static_cast<std::uint32_t
>(seed[32 + i * 4])
2008 | (
static_cast<std::uint32_t
>(seed[32 + i * 4 + 1]) << 8)
2009 | (
static_cast<std::uint32_t
>(seed[32 + i * 4 + 2]) << 16)
2010 | (
static_cast<std::uint32_t
>(seed[32 + i * 4 + 3]) << 24);
2014 m_bytesSinceReseed = 0;
2015 detail::SecureWipe(seed.data(), seed.size());
2016 detail::SecureWipe(m_buffer.data(), m_buffer.size());
2020 inline ChaCha20::result_type ChaCha20::operator()()
2022 reseedIfNecessary();
2023 if (m_bufferPos == 64)
2026 std::uint64_t result = 0;
2027 for (
int i = 0; i < 8; ++i)
2028 result |=
static_cast<std::uint64_t
>(m_buffer[m_bufferPos + i]) << (8 * i);
2030 m_bytesSinceReseed += 8;
2034 inline void ChaCha20::discard(
const unsigned long long n)
2036 for (
unsigned long long i = 0; i < n; ++i)
operator()();
2040 inline void Reseed(std::uint64_t seed)
2058 template <
class T =
int, std::enable_if_t<std::is_
integral_v<T>>* =
nullptr>
2063 std::uniform_int_distribution<T> dist(min, max);
2070 template <
class T =
int, std::enable_if_t<std::is_
integral_v<T>>* =
nullptr>
2074 assert(max >= T{0});
2082 template <
class T =
double, std::enable_if_t<std::is_
floating_po
int_v<T>>* =
nullptr>
2086 assert(std::isfinite(min) && std::isfinite(max) && min <= max);
2087 std::uniform_real_distribution<T> dist(min, max);
2095 inline bool RandBool(
double p = 0.5)
2097 assert(std::isfinite(p) && p >= 0.0 && p <= 1.0);
2098 std::bernoulli_distribution dist(p);
2106 template <
class Engine>
2108 inline bool RandBool(Engine& engine,
double p = 0.5)
2110 assert(std::isfinite(p) && p >= 0.0 && p <= 1.0);
2111 std::bernoulli_distribution dist(p);
2112 return dist(engine);
2121 assert(p >= 0.0 && p <= 1.0);
2129 template <
class Engine>
2133 assert(p >= 0.0 && p <= 1.0);
2142 template <
class CharT,
2143 std::enable_if_t<detail::is_character_v<CharT>>* =
nullptr>
2148 using IntT = std::int64_t;
2149 std::uniform_int_distribution<IntT> dist(
2150 static_cast<IntT
>(min),
static_cast<IntT
>(max));
2157 template <
class CharT,
2158 std::enable_if_t<detail::is_character_v<CharT>>* =
nullptr>
2170 template <
class CharT,
class Engine,
2171 std::enable_if_t<detail::is_character_v<CharT>>* =
nullptr>
2173 inline CharT
RandChar(Engine& engine, CharT min, CharT max)
2176 using IntT = std::int64_t;
2177 std::uniform_int_distribution<IntT> dist(
2178 static_cast<IntT
>(min),
static_cast<IntT
>(max));
2179 return static_cast<CharT
>(dist(engine));
2186 template <
class CharT,
class Engine,
2187 std::enable_if_t<detail::is_character_v<CharT>>* =
nullptr>
2218 inline constexpr std::uint64_t HashSetThresholdK = 64;
2222 inline std::string_view CharSetString(CharSet cs)
noexcept
2226 case CharSet::Alphanumeric:
2227 return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
2228 case CharSet::Alpha:
2229 return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
2230 case CharSet::Lower:
2231 return "abcdefghijklmnopqrstuvwxyz";
2232 case CharSet::Upper:
2233 return "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
2234 case CharSet::Digit:
2235 return "0123456789";
2237 return "0123456789abcdef";
2238 case CharSet::Printable:
2239 return "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
2240 case CharSet::Base64:
2241 return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2242 case CharSet::Base64UrlSafe:
2243 return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
2256 const auto charset = detail::CharSetString(cs);
2257 if (charset.empty())
2258 throw std::invalid_argument(
"RandChar: charset is empty");
2260 std::uniform_int_distribution<std::size_t> dist(0, charset.size() - 1);
2261 return charset[dist(rng)];
2268 template <
class Engine>
2270 inline char RandChar(Engine& engine, CharSet cs)
2272 const auto charset = detail::CharSetString(cs);
2273 if (charset.empty())
2274 throw std::invalid_argument(
"RandChar: charset is empty");
2275 std::uniform_int_distribution<std::size_t> dist(0, charset.size() - 1);
2276 return charset[dist(engine)];
2286 template <
class Container,
2287 std::enable_if_t<detail::is_random_access_container_v<Container>>* =
nullptr>
2292 throw std::invalid_argument(
"RandElement: empty container");
2300 template <
class Container,
2301 std::enable_if_t<detail::is_random_access_container_v<std::decay_t<Container>>>* =
nullptr>
2303 inline typename std::decay_t<Container>::value_type
RandElement(Container&& c)
2306 throw std::invalid_argument(
"RandElement: empty container");
2316 std::enable_if_t<detail::is_random_access_iterator_v<It>>* =
nullptr>
2320 using Diff =
typename std::iterator_traits<It>::difference_type;
2321 const Diff n = std::distance(first, last);
2323 throw std::invalid_argument(
"RandElement: empty range");
2333 std::enable_if_t<detail::is_input_iterator_v<It>
2334 && !detail::is_random_access_iterator_v<It>>* =
nullptr>
2339 throw std::invalid_argument(
"RandElement: empty range");
2340 It selected = first;
2342 for (
typename std::iterator_traits<It>::difference_type i = 1;
2343 first != last; ++first, ++i)
2345 if (
RandInt<
typename std::iterator_traits<It>::difference_type>(0, i) == 0)
2356 template <
class It,
class Engine,
2357 std::enable_if_t<detail::is_random_access_iterator_v<It>>* =
nullptr>
2361 using Diff =
typename std::iterator_traits<It>::difference_type;
2362 const Diff n = std::distance(first, last);
2364 throw std::invalid_argument(
"RandElement: empty range");
2365 return std::next(first,
RandInt<Diff>(engine, Diff{0}, n - 1));
2373 template <
class It,
class Engine,
2374 std::enable_if_t<detail::is_input_iterator_v<It>
2375 && !detail::is_random_access_iterator_v<It>>* =
nullptr>
2380 throw std::invalid_argument(
"RandElement: empty range");
2381 It selected = first;
2383 for (
typename std::iterator_traits<It>::difference_type i = 1;
2384 first != last; ++first, ++i)
2386 if (
RandInt<
typename std::iterator_traits<It>::difference_type>(
2387 engine,
typename std::iterator_traits<It>::difference_type{0}, i) == 0)
2401 template <
class T =
double, std::enable_if_t<std::is_
floating_po
int_v<T>>* =
nullptr>
2405 assert(std::isfinite(mean) && std::isfinite(stddev) && stddev > T{0});
2406 std::normal_distribution<T> dist(mean, stddev);
2415 template <
class Engine,
class T =
double, std::enable_if_t<std::is_
floating_po
int_v<T>>* =
nullptr>
2417 inline T
RandNormal(Engine& engine, T mean = T{0}, T stddev = T{1})
2419 assert(std::isfinite(mean) && std::isfinite(stddev) && stddev > T{0});
2420 std::normal_distribution<T> dist(mean, stddev);
2421 return dist(engine);
2426 template <
class Container,
2427 std::enable_if_t<detail::is_random_access_container_v<Container>>* =
nullptr>
2440 template <
class It,
class T,
2441 std::enable_if_t<detail::is_rand_fillable_v<It, T>>* =
nullptr>
2446 if constexpr (std::is_integral_v<T>)
2448 std::uniform_int_distribution<T> dist(min, max);
2449 for (; first != last; ++first) *first = dist(rng);
2453 std::uniform_real_distribution<T> dist(min, max);
2454 for (; first != last; ++first) *first = dist(rng);
2464 template <
class It,
class T,
class Engine,
2465 std::enable_if_t<detail::is_rand_fillable_v<It, T>>* =
nullptr>
2466 inline void RandFill(Engine& engine, It first, It last, T min, T max)
2469 if constexpr (std::is_integral_v<T>)
2471 std::uniform_int_distribution<T> dist(min, max);
2472 for (; first != last; ++first) *first = dist(engine);
2476 std::uniform_real_distribution<T> dist(min, max);
2477 for (; first != last; ++first) *first = dist(engine);
2487 std::enable_if_t<std::is_integral_v<T>>* =
nullptr>
2495 std::uniform_int_distribution<T> dist(min, max);
2496 for (std::size_t i = 0; i < n; ++i)
2497 v.push_back(dist(rng));
2507 std::enable_if_t<std::is_floating_point_v<T>>* =
nullptr>
2515 std::uniform_real_distribution<T> dist(min, max);
2516 for (std::size_t i = 0; i < n; ++i)
2517 v.push_back(dist(rng));
2527 template <
class T,
class Engine,
2528 std::enable_if_t<std::is_integral_v<T>>* =
nullptr>
2530 inline std::vector<T>
RandVector(Engine& engine, T min, T max, std::size_t n)
2535 std::uniform_int_distribution<T> dist(min, max);
2536 for (std::size_t i = 0; i < n; ++i)
2537 v.push_back(dist(engine));
2547 template <
class T,
class Engine,
2548 std::enable_if_t<std::is_floating_point_v<T>>* =
nullptr>
2550 inline std::vector<T>
RandVector(Engine& engine, T min, T max, std::size_t n)
2555 std::uniform_real_distribution<T> dist(min, max);
2556 for (std::size_t i = 0; i < n; ++i)
2557 v.push_back(dist(engine));
2564 template <
class WeightContainer>
2566 inline typename WeightContainer::size_type RandWeighted(
const WeightContainer& weights)
2568 assert(!weights.empty() && std::all_of(weights.begin(), weights.end(), [](
auto w) { return w >= 0; }) && std::any_of(weights.begin(), weights.end(), [](
auto w) { return w > 0; }));
2569 using Size =
typename WeightContainer::size_type;
2570 std::discrete_distribution<Size> dist(weights.begin(), weights.end());
2571 return dist(DefaultEngine());
2578 template <
class Engine,
class WeightContainer>
2580 inline typename WeightContainer::size_type
RandWeighted(Engine& engine,
const WeightContainer& weights)
2582 assert(!weights.empty() && std::all_of(weights.begin(), weights.end(), [](
auto w) { return w >= 0; }) && std::any_of(weights.begin(), weights.end(), [](
auto w) { return w > 0; }));
2583 using Size =
typename WeightContainer::size_type;
2584 std::discrete_distribution<Size> dist(weights.begin(), weights.end());
2585 return dist(engine);
2591 template <
class IntType>
2593 inline IntType
RandWeighted(std::discrete_distribution<IntType>& dist)
2602 template <
class Engine,
class IntType>
2604 inline IntType
RandWeighted(Engine& engine, std::discrete_distribution<IntType>& dist)
2606 return dist(engine);
2614 template <
class T,
class Engine, std::enable_if_t<std::is_
integral_v<T>>* =
nullptr>
2619 std::uniform_int_distribution<T> dist(min, max);
2620 return dist(engine);
2628 template <
class T,
class Engine, std::enable_if_t<std::is_
floating_po
int_v<T>>* =
nullptr>
2630 inline T
RandReal(Engine& engine, T min = T{0}, T max = T{1})
2632 assert(std::isfinite(min) && std::isfinite(max) && min <= max);
2633 std::uniform_real_distribution<T> dist(min, max);
2634 return dist(engine);
2646 template <
class Container,
2647 std::enable_if_t<detail::is_random_access_container_v<Container>>* =
nullptr>
2649 inline auto RandSample(
const Container& c,
typename Container::size_type n)
2651 using T =
typename Container::value_type;
2652 using Size =
typename Container::size_type;
2653 std::vector<T> pool(c.begin(), c.end());
2654 const Size size =
static_cast<Size
>(pool.size());
2655 if (n >= size)
return pool;
2657 for (Size i = 0; i < n; ++i)
2659 std::uniform_int_distribution<Size> dist(i, size - 1);
2660 const Size j = dist(rng);
2661 auto tmp = std::move(pool[i]);
2662 pool[i] = std::move(pool[j]);
2663 pool[j] = std::move(tmp);
2677 std::enable_if_t<detail::is_random_access_iterator_v<It>>* =
nullptr>
2679 inline std::vector<typename std::iterator_traits<It>::value_type>
2680 RandSample(It first, It last,
typename std::iterator_traits<It>::difference_type n)
2682 using Diff =
typename std::iterator_traits<It>::difference_type;
2683 using T =
typename std::iterator_traits<It>::value_type;
2684 const Diff size = std::distance(first, last);
2685 if (n <= 0 || size == 0)
2688 return std::vector<T>(first, last);
2693 const auto sizeU =
static_cast<std::uint64_t
>(size);
2698 std::unordered_set<Diff> selected;
2699 selected.reserve(
static_cast<std::size_t
>(n));
2700 std::vector<T> result;
2701 result.reserve(
static_cast<std::size_t
>(n));
2702 while (result.size() <
static_cast<std::size_t
>(n))
2704 std::uniform_int_distribution<Diff> dist(Diff{0},
static_cast<Diff
>(sizeU - 1));
2705 const Diff idx = dist(rng);
2706 if (selected.insert(idx).second)
2707 result.push_back(first[idx]);
2713 std::vector<Diff> indices(
static_cast<std::size_t
>(size));
2714 for (Diff i = 0; i < size; ++i)
2715 indices[
static_cast<std::size_t
>(i)] = i;
2718 for (Diff i = 0; i < n; ++i)
2720 std::uniform_int_distribution<Diff> dist(i,
static_cast<Diff
>(size - 1));
2721 const Diff j = dist(rng);
2722 std::swap(indices[
static_cast<std::size_t
>(i)],
2723 indices[
static_cast<std::size_t
>(j)]);
2726 std::vector<T> result;
2727 result.reserve(
static_cast<std::size_t
>(n));
2728 for (Diff i = 0; i < n; ++i)
2729 result.push_back(first[indices[
static_cast<std::size_t
>(i)]]);
2735 std::enable_if_t<detail::is_input_iterator_v<It>
2736 && !detail::is_random_access_iterator_v<It>>* =
nullptr>
2738 inline std::vector<typename std::iterator_traits<It>::value_type>
2739 RandSample(It first, It last,
typename std::iterator_traits<It>::difference_type n)
2741 using Diff =
typename std::iterator_traits<It>::difference_type;
2742 using T =
typename std::iterator_traits<It>::value_type;
2746 std::vector<T> reservoir;
2747 reservoir.reserve(
static_cast<std::size_t
>(n));
2751 for (; i < n && first != last; ++i, ++first)
2752 reservoir.push_back(*first);
2760 for (; first != last; ++i, ++first)
2762 std::uniform_int_distribution<Diff> dist(Diff{0}, i);
2763 const Diff j = dist(rng);
2765 reservoir[
static_cast<std::size_t
>(j)] = *first;
2771 template <
class It,
class Engine,
2772 std::enable_if_t<detail::is_random_access_iterator_v<It>>* =
nullptr>
2774 inline std::vector<typename std::iterator_traits<It>::value_type>
2775 RandSample(Engine& engine, It first, It last,
typename std::iterator_traits<It>::difference_type n)
2777 using Diff =
typename std::iterator_traits<It>::difference_type;
2778 using T =
typename std::iterator_traits<It>::value_type;
2779 const Diff size = std::distance(first, last);
2780 if (n <= 0 || size == 0)
2783 return std::vector<T>(first, last);
2785 const auto sizeU =
static_cast<std::uint64_t
>(size);
2789 std::unordered_set<Diff> selected;
2790 selected.reserve(
static_cast<std::size_t
>(n));
2791 std::vector<T> result;
2792 result.reserve(
static_cast<std::size_t
>(n));
2793 while (result.size() <
static_cast<std::size_t
>(n))
2795 std::uniform_int_distribution<Diff> dist(Diff{0},
static_cast<Diff
>(sizeU - 1));
2796 const Diff idx = dist(engine);
2797 if (selected.insert(idx).second)
2798 result.push_back(first[idx]);
2803 std::vector<Diff> indices(
static_cast<std::size_t
>(size));
2804 for (Diff i = 0; i < size; ++i)
2805 indices[
static_cast<std::size_t
>(i)] = i;
2807 for (Diff i = 0; i < n; ++i)
2809 std::uniform_int_distribution<Diff> dist(i,
static_cast<Diff
>(size - 1));
2810 const Diff j = dist(engine);
2811 std::swap(indices[
static_cast<std::size_t
>(i)],
2812 indices[
static_cast<std::size_t
>(j)]);
2815 std::vector<T> result;
2816 result.reserve(
static_cast<std::size_t
>(n));
2817 for (Diff i = 0; i < n; ++i)
2818 result.push_back(first[indices[
static_cast<std::size_t
>(i)]]);
2823 template <
class It,
class Engine,
2824 std::enable_if_t<detail::is_input_iterator_v<It>
2825 && !detail::is_random_access_iterator_v<It>>* =
nullptr>
2827 inline std::vector<typename std::iterator_traits<It>::value_type>
2828 RandSample(Engine& engine, It first, It last,
typename std::iterator_traits<It>::difference_type n)
2830 using Diff =
typename std::iterator_traits<It>::difference_type;
2831 using T =
typename std::iterator_traits<It>::value_type;
2835 std::vector<T> reservoir;
2836 reservoir.reserve(
static_cast<std::size_t
>(n));
2839 for (; i < n && first != last; ++i, ++first)
2840 reservoir.push_back(*first);
2846 for (; first != last; ++i, ++first)
2848 std::uniform_int_distribution<Diff> dist(Diff{0}, i);
2849 const Diff j = dist(engine);
2851 reservoir[
static_cast<std::size_t
>(j)] = *first;
2860 inline std::vector<std::size_t> RandPermutation(std::size_t n)
2862 std::vector<std::size_t> perm(n);
2863 for (std::size_t i = 0; i < n; ++i) perm[i] = i;
2864 if (n < 2)
return perm;
2865 auto& rng = DefaultEngine();
2866 for (std::size_t i = n - 1; i > 0; --i)
2868 std::uniform_int_distribution<std::size_t> dist(0, i);
2869 const std::size_t j = dist(rng);
2886 inline std::string
RandString(std::size_t length, std::string_view charset =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
2888 if (charset.empty())
2889 throw std::invalid_argument(
"RandString: charset is empty");
2890 std::string result(length,
'\0');
2892 std::uniform_int_distribution<std::size_t> dist(0, charset.size() - 1);
2893 for (std::size_t i = 0; i < length; ++i)
2894 result[i] = charset[dist(rng)];
2903 inline std::string
RandString(std::size_t n, CharSet cs)
2905 return RandString(n, detail::CharSetString(cs));
2913 template <
class Engine>
2915 inline std::string
RandString(Engine& engine, std::size_t n, CharSet cs)
2917 const auto charset = detail::CharSetString(cs);
2918 if (charset.empty())
2919 throw std::invalid_argument(
"RandString: charset is empty");
2920 std::string result(n,
'\0');
2921 std::uniform_int_distribution<std::size_t> dist(0, charset.size() - 1);
2922 for (std::size_t i = 0; i < n; ++i)
2923 result[i] = charset[dist(engine)];
2930 template <
class T =
double, std::enable_if_t<std::is_
floating_po
int_v<T>>* =
nullptr>
2934 assert(std::isfinite(lambda) && lambda > T{0});
2935 std::exponential_distribution<T> dist(lambda);
2943 template <
class Engine,
class T =
double, std::enable_if_t<std::is_
floating_po
int_v<T>>* =
nullptr>
2947 assert(std::isfinite(lambda) && lambda > T{0});
2948 std::exponential_distribution<T> dist(lambda);
2949 return dist(engine);
2955 template <
class T =
int, std::enable_if_t<std::is_
integral_v<T>>* =
nullptr>
2959 assert(std::isfinite(mean) && mean >= 0.0);
2960 if (mean == 0.0)
return T{0};
2961 std::poisson_distribution<T> dist(mean);
2969 template <
class Engine,
class T =
int, std::enable_if_t<std::is_
integral_v<T>>* =
nullptr>
2973 assert(std::isfinite(mean) && mean >= 0.0);
2974 if (mean == 0.0)
return T{0};
2975 std::poisson_distribution<T> dist(mean);
2976 return dist(engine);
2983 template <
class T =
double, std::enable_if_t<std::is_
floating_po
int_v<T>>* =
nullptr>
2987 assert(std::isfinite(alpha) && std::isfinite(beta) && alpha > T{0} && beta > T{0});
2988 std::gamma_distribution<T> dist(alpha, beta);
2997 template <
class Engine,
class T =
double, std::enable_if_t<std::is_
floating_po
int_v<T>>* =
nullptr>
2999 inline T
RandGamma(Engine& engine, T alpha = T{1}, T beta = T{1})
3001 assert(std::isfinite(alpha) && std::isfinite(beta) && alpha > T{0} && beta > T{0});
3002 std::gamma_distribution<T> dist(alpha, beta);
3003 return dist(engine);
3010 template <
class T =
int, std::enable_if_t<std::is_
integral_v<T>>* =
nullptr>
3014 assert(t >= 0 && std::isfinite(p) && p >= 0.0 && p <= 1.0);
3015 std::binomial_distribution<T> dist(t, p);
3024 template <
class T =
int,
class Engine, std::enable_if_t<std::is_
integral_v<T>>* =
nullptr>
3028 assert(t >= 0 && std::isfinite(p) && p >= 0.0 && p <= 1.0);
3029 std::binomial_distribution<T> dist(t, p);
3030 return dist(engine);
3037 template <
class T =
double, std::enable_if_t<std::is_
floating_po
int_v<T>>* =
nullptr>
3041 assert(std::isfinite(mean) && std::isfinite(stddev) && stddev > T{0});
3042 std::lognormal_distribution<T> dist(mean, stddev);
3051 template <
class T =
double,
class Engine, std::enable_if_t<std::is_
floating_po
int_v<T>>* =
nullptr>
3055 assert(std::isfinite(mean) && std::isfinite(stddev) && stddev > T{0});
3056 std::lognormal_distribution<T> dist(mean, stddev);
3057 return dist(engine);
3063 template <
class T =
int, std::enable_if_t<std::is_
integral_v<T>>* =
nullptr>
3067 assert(p > 0.0 && p <= 1.0);
3068 std::geometric_distribution<T> dist(p);
3076 template <
class T =
int,
class Engine, std::enable_if_t<std::is_
integral_v<T>>* =
nullptr>
3080 assert(p > 0.0 && p <= 1.0);
3081 std::geometric_distribution<T> dist(p);
3082 return dist(engine);
3089 template <
class T =
double, std::enable_if_t<std::is_
floating_po
int_v<T>>* =
nullptr>
3093 assert(std::isfinite(a) && std::isfinite(b) && b > T{0});
3094 std::cauchy_distribution<T> dist(a, b);
3103 template <
class T =
double,
class Engine, std::enable_if_t<std::is_
floating_po
int_v<T>>* =
nullptr>
3107 assert(std::isfinite(a) && std::isfinite(b) && b > T{0});
3108 std::cauchy_distribution<T> dist(a, b);
3109 return dist(engine);
3116 template <
class T =
double, std::enable_if_t<std::is_
floating_po
int_v<T>>* =
nullptr>
3120 assert(std::isfinite(a) && std::isfinite(b) && a > T{0} && b > T{0});
3121 std::weibull_distribution<T> dist(a, b);
3130 template <
class T =
double,
class Engine, std::enable_if_t<std::is_
floating_po
int_v<T>>* =
nullptr>
3134 assert(std::isfinite(a) && std::isfinite(b) && a > T{0} && b > T{0});
3135 std::weibull_distribution<T> dist(a, b);
3136 return dist(engine);
3143 template <
class T =
double, std::enable_if_t<std::is_
floating_po
int_v<T>>* =
nullptr>
3147 assert(std::isfinite(a) && std::isfinite(b) && b > T{0});
3148 std::extreme_value_distribution<T> dist(a, b);
3157 template <
class T =
double,
class Engine, std::enable_if_t<std::is_
floating_po
int_v<T>>* =
nullptr>
3161 assert(std::isfinite(a) && std::isfinite(b) && b > T{0});
3162 std::extreme_value_distribution<T> dist(a, b);
3163 return dist(engine);
3169 template <
class T =
double, std::enable_if_t<std::is_
floating_po
int_v<T>>* =
nullptr>
3173 assert(std::isfinite(n) && n > T{0});
3174 std::chi_squared_distribution<T> dist(n);
3182 template <
class T =
double,
class Engine, std::enable_if_t<std::is_
floating_po
int_v<T>>* =
nullptr>
3186 assert(std::isfinite(n) && n > T{0});
3187 std::chi_squared_distribution<T> dist(n);
3188 return dist(engine);
3194 template <
class T =
double, std::enable_if_t<std::is_
floating_po
int_v<T>>* =
nullptr>
3198 assert(std::isfinite(n) && n > T{0});
3199 std::student_t_distribution<T> dist(n);
3207 template <
class T =
double,
class Engine, std::enable_if_t<std::is_
floating_po
int_v<T>>* =
nullptr>
3211 assert(std::isfinite(n) && n > T{0});
3212 std::student_t_distribution<T> dist(n);
3213 return dist(engine);
3220 template <
class T =
double, std::enable_if_t<std::is_
floating_po
int_v<T>>* =
nullptr>
3224 assert(std::isfinite(m) && std::isfinite(n) && m > T{0} && n > T{0});
3225 std::fisher_f_distribution<T> dist(m, n);
3234 template <
class T =
double,
class Engine, std::enable_if_t<std::is_
floating_po
int_v<T>>* =
nullptr>
3238 assert(std::isfinite(m) && std::isfinite(n) && m > T{0} && n > T{0});
3239 std::fisher_f_distribution<T> dist(m, n);
3240 return dist(engine);
3248 template <
class T =
double, std::enable_if_t<std::is_
floating_po
int_v<T>>* =
nullptr>
3252 assert(std::isfinite(a) && std::isfinite(b) && a > T{0} && b > T{0});
3253 std::gamma_distribution<T> distA(a, T{1});
3254 std::gamma_distribution<T> distB(b, T{1});
3256 const T x = distA(rng);
3257 const T y = distB(rng);
3258 const T sum = x + y;
3260 return RandBool(rng,
static_cast<double>(a) /
static_cast<double>(a + b)) ? T{1} : T{0};
3269 template <
class T =
double,
class Engine, std::enable_if_t<std::is_
floating_po
int_v<T>>* =
nullptr>
3271 inline T
RandBeta(Engine& engine, T a = T{1}, T b = T{1})
3273 assert(std::isfinite(a) && std::isfinite(b) && a > T{0} && b > T{0});
3274 std::gamma_distribution<T> distA(a, T{1});
3275 std::gamma_distribution<T> distB(b, T{1});
3276 const T x = distA(engine);
3277 const T y = distB(engine);
3278 const T sum = x + y;
3280 return RandBool(engine,
static_cast<double>(a) /
static_cast<double>(a + b)) ? T{1} : T{0};
3287 template <
int N,
class T = std::u
int64_t, std::enable_if_t<std::is_
integral_v<T> && (N > 0) && (N <= 64) && (N <= std::numeric_limits<T>::digits)>* =
nullptr>
3289 inline T RandBits() noexcept
3291 auto& rng = DefaultEngine();
3292 if constexpr (N == 64)
3293 return static_cast<T>(rng());
3295 return static_cast<T>(rng() & ((std::u
int64_t{1} << N) - 1));
3302 template <
class Engine>
3304 inline std::string
RandUUID(Engine& engine)
3306 static constexpr char hex[] =
"0123456789abcdef";
3307 std::string uuid(36,
'-');
3311 for (
int i = 0; i < 8; ++i)
3312 uuid[i] = hex[(u1 >> (i * 4)) & 0xFU];
3313 for (
int i = 0; i < 4; ++i)
3314 uuid[9 + i] = hex[(u1 >> ((8 + i) * 4)) & 0xFU];
3316 for (
int i = 1; i < 4; ++i)
3317 uuid[14 + i] = hex[(u1 >> ((12 + i) * 4)) & 0xFU];
3318 uuid[19] = hex[8 + ((u2 >> 0) & 0x3U)];
3319 for (
int i = 1; i < 4; ++i)
3320 uuid[19 + i] = hex[(u2 >> (i * 4)) & 0xFU];
3321 for (
int i = 0; i < 12; ++i)
3322 uuid[24 + i] = hex[(u2 >> ((4 + i) * 4)) & 0xFU];
3328 inline std::string RandUUID()
3330 return RandUUID(DefaultEngine());
3338 static_assert(std::is_same_v<SplitMix64::result_type, std::uint64_t>);
3339 static_assert(std::is_same_v<Xoshiro256StarStar::result_type, std::uint64_t>);
3340 static_assert(std::is_same_v<Xoroshiro128StarStar::result_type, std::uint64_t>);
3341 static_assert(std::is_same_v<Xoshiro128StarStar::result_type, std::uint32_t>);
3342 static_assert(std::is_same_v<Xoroshiro64StarStar::result_type, std::uint32_t>);
3343 static_assert(std::is_same_v<SFC64::result_type, std::uint64_t>);
3344 static_assert(std::is_same_v<RomuDuoJr::result_type, std::uint64_t>);
3345 static_assert(std::is_same_v<ChaCha20::result_type, std::uint64_t>);
3346 static_assert(SplitMix64::min() < SplitMix64::max());
3347 static_assert(Xoshiro256StarStar::min() < Xoshiro256StarStar::max());
3348 static_assert(Xoroshiro128StarStar::min() < Xoroshiro128StarStar::max());
3349 static_assert(Xoshiro128StarStar::min() < Xoshiro128StarStar::max());
3350 static_assert(Xoroshiro64StarStar::min() < Xoroshiro64StarStar::max());
3351 static_assert(SFC64::min() < SFC64::max());
3352 static_assert(RomuDuoJr::min() < RomuDuoJr::max());
3363 template <
class CharT,
class Traits,
class Engine,
3364 std::enable_if_t<detail::is_serializable_engine_v<Engine>>* =
nullptr>
3365 std::basic_ostream<CharT, Traits>&
3366 operator<<(std::basic_ostream<CharT, Traits>& os,
const Engine& engine)
3368 auto state = engine.serialize();
3369 auto it = state.begin();
3370 if (it != state.end())
3373 for (++it; it != state.end(); ++it)
3374 os << os.widen(
' ') << *it;
3382 template <
class CharT,
class Traits,
class Engine,
3383 std::enable_if_t<detail::is_serializable_engine_v<Engine>>* =
nullptr>
3384 std::basic_istream<CharT, Traits>&
3385 operator>>(std::basic_istream<CharT, Traits>& is, Engine& engine)
3387 typename Engine::state_type state{};
3389 for (; i < state.size() && is; ++i)
3392 if (i == state.size() && is)
3394 engine.deserialize(state);
3398 is.setstate(std::ios_base::failbit);
#define RANDX_NODISCARD_CXX20
定义 RandX_Cpp17.hpp:124
ChaCha20 密码学安全伪随机数生成器(CSPRNG),64 位输出,符合 RFC 8439。
定义 RandX.hpp:680
ChaCha20(const ChaCha20 &)=delete
ChaCha20 & operator=(ChaCha20 &&other) noexcept
ChaCha20 & operator=(const ChaCha20 &)=delete
static RANDX_NODISCARD_CXX20 constexpr result_type max() noexcept
输出范围上界
定义 RandX_Cpp17.hpp:792
ChaCha20(ChaCha20 &&other) noexcept
constexpr RomuDuoJr(std::uint64_t seed=DefaultSeed) noexcept
以指定种子构造引擎
RANDX_NODISCARD_CXX20 constexpr RomuDuoJr(SeedSeq &seq)
从 std::seed_seq 播种
friend bool operator!=(const RomuDuoJr &lhs, const RomuDuoJr &rhs) noexcept
定义 RandX_Cpp17.hpp:717
constexpr RomuDuoJr(state_type state) noexcept
从状态数组直接构造
constexpr result_type operator()() noexcept
生成下一个 64 位随机数
friend bool operator!=(const SFC64 &lhs, const SFC64 &rhs) noexcept
定义 RandX_Cpp17.hpp:636
RANDX_NODISCARD_CXX20 constexpr SFC64(SeedSeq &seq)
从 std::seed_seq 播种
constexpr SFC64(state_type state) noexcept
从状态数组直接构造
constexpr SFC64(std::uint64_t seed=DefaultSeed) noexcept
以指定种子构造引擎
constexpr result_type operator()() noexcept
生成下一个 64 位随机数
SplitMix64 伪随机数生成器,64 位输出,周期 2^64。
定义 RandX.hpp:165
constexpr result_type operator()() noexcept
生成下一个 64 位随机数
RANDX_NODISCARD_CXX20 constexpr SplitMix64(state_type state=DefaultSeed) noexcept
以指定状态构造引擎
friend bool operator!=(const SplitMix64 &lhs, const SplitMix64 &rhs) noexcept
定义 RandX_Cpp17.hpp:217
RANDX_NODISCARD_CXX20 constexpr SplitMix64(SeedSeq &seq)
从 std::seed_seq 播种
RANDX_NODISCARD_CXX20 constexpr Xoroshiro128StarStar(state_type state) noexcept
从状态数组直接构造
friend bool operator!=(const Xoroshiro128StarStar &lhs, const Xoroshiro128StarStar &rhs) noexcept
定义 RandX_Cpp17.hpp:393
constexpr result_type operator()() noexcept
生成下一个 64 位随机数
RANDX_NODISCARD_CXX20 constexpr Xoroshiro128StarStar(SeedSeq &seq)
从 std::seed_seq 播种
RANDX_NODISCARD_CXX20 constexpr Xoroshiro128StarStar(std::uint64_t seed=DefaultSeed) noexcept
以指定种子构造引擎
RANDX_NODISCARD_CXX20 constexpr Xoroshiro64StarStar(state_type state) noexcept
从状态数组直接构造
friend bool operator!=(const Xoroshiro64StarStar &lhs, const Xoroshiro64StarStar &rhs) noexcept
定义 RandX_Cpp17.hpp:559
RANDX_NODISCARD_CXX20 constexpr Xoroshiro64StarStar(std::uint64_t seed=DefaultSeed) noexcept
以指定种子构造引擎
constexpr result_type operator()() noexcept
生成下一个 32 位随机数
RANDX_NODISCARD_CXX20 constexpr Xoroshiro64StarStar(SeedSeq &seq)
从 std::seed_seq 播种
RANDX_NODISCARD_CXX20 constexpr Xoshiro128StarStar(std::uint64_t seed=DefaultSeed) noexcept
以指定种子构造引擎
constexpr result_type operator()() noexcept
生成下一个 32 位随机数
RANDX_NODISCARD_CXX20 constexpr Xoshiro128StarStar(SeedSeq &seq)
从 std::seed_seq 播种
RANDX_NODISCARD_CXX20 constexpr Xoshiro128StarStar(state_type state) noexcept
从状态数组直接构造
friend bool operator!=(const Xoshiro128StarStar &lhs, const Xoshiro128StarStar &rhs) noexcept
定义 RandX_Cpp17.hpp:481
Xoshiro256** 伪随机数生成器,64 位输出,周期 2^256-1。
定义 RandX.hpp:235
RANDX_NODISCARD_CXX20 constexpr Xoshiro256StarStar(state_type state) noexcept
从状态数组直接构造
friend bool operator!=(const Xoshiro256StarStar &lhs, const Xoshiro256StarStar &rhs) noexcept
定义 RandX_Cpp17.hpp:305
RANDX_NODISCARD_CXX20 constexpr Xoshiro256StarStar(SeedSeq &seq)
从 std::seed_seq 播种
RANDX_NODISCARD_CXX20 constexpr Xoshiro256StarStar(std::uint64_t seed=DefaultSeed) noexcept
以指定种子构造引擎
constexpr result_type operator()() noexcept
生成下一个 64 位随机数
bool RandBernoulli(double p=0.5)
伯努利分布(RandBool 的别名封装,对齐 <random> 命名)
定义 RandX.hpp:2045
bool RandBool(double p=0.5)
生成随机布尔值
定义 RandX.hpp:2021
T RandReal(T min=T{0}, T max=T{1})
生成 [min, max) 范围内的随机浮点数
定义 RandX.hpp:2010
CharT RandChar(CharT min, CharT max)
生成 [min, max] 范围内的随机字符
定义 RandX.hpp:2070
T RandInt(T min, T max)
生成 [min, max] 范围内的随机整数
定义 RandX.hpp:1986
decltype(auto) RandElement(Container &c)
从容器中随机取一个元素(左值容器,返回引用)
定义 RandX.hpp:2129
std::uint64_t SecureSeed()
生成密码学安全的 64 位随机种子
定义 RandX.hpp:1730
void SecureRandomBytes(void *buf, std::size_t n)
用 OS 密码学熵源填充 [buf, buf+n) 字节
定义 RandX.hpp:1720
void ReseedRandom()
重置默认引擎为真随机种子
定义 RandX.hpp:1969
bool IsOsCryptoEntropyAvailable() noexcept
检测 OS 密码学熵源是否可用
定义 RandX.hpp:1741
void Reseed(std::uint64_t seed)
重置默认引擎的种子(用于测试复现)
定义 RandX.hpp:1963
void RandFill(It first, It last, T min, T max)
用 [min, max] 范围的随机整数填充迭代器区间
定义 RandX.hpp:2277
void RandShuffle(Container &&c)
随机打乱容器
定义 RandX.hpp:2263
WeightContainer::size_type RandWeighted(const WeightContainer &weights)
按权重随机选取索引
定义 RandX.hpp:2413
auto RandSample(const Container &c, typename Container::size_type n)
无放回抽样:从容器中随机抽取 n 个元素(Fisher-Yates 前 n 步)
定义 RandX.hpp:2589
std::vector< T > RandVector(T min, T max, std::size_t n)
生成含 n 个随机整数的 vector
定义 RandX.hpp:2339
T RandNormal(T mean=T{0}, T stddev=T{1})
生成正态分布随机数
定义 RandX.hpp:2239
@ Base64
定义 RandX.hpp:2513
@ Base64UrlSafe
定义 RandX.hpp:2514
@ Printable
定义 RandX.hpp:2512
@ Alphanumeric
定义 RandX.hpp:2506
static constexpr result_type min() noexcept
输出范围下界
定义 RandX.hpp:1438
constexpr state_type serialize() const noexcept
序列化引擎状态
定义 RandX.hpp:1080
constexpr void longJump() noexcept
前进 2^96 步,用于创建更稀疏的并行子序列
定义 RandX.hpp:1283
constexpr state_type serialize() const noexcept
序列化引擎状态
定义 RandX.hpp:1657
constexpr std::array< std::uint64_t, N > generateSeedSequence() noexcept
生成 N 个高质量的 64 位种子序列
定义 RandX.hpp:1058
constexpr result_type operator()() noexcept
生成下一个 32 位随机数
定义 RandX.hpp:1496
constexpr RomuDuoJr(std::uint64_t seed=DefaultSeed) noexcept
以指定种子构造引擎
定义 RandX.hpp:1612
std::array< std::uint64_t, 2 > state_type
状态类型(2×uint64)
定义 RandX.hpp:611
constexpr void jump() noexcept
前进 2^128 步,用于创建并行子序列
定义 RandX.hpp:1135
static constexpr result_type min() noexcept
输出范围下界
定义 RandX.hpp:1307
static constexpr result_type min() noexcept
输出范围下界
定义 RandX.hpp:727
std::array< std::uint64_t, 2 > state_type
状态类型(2×uint64)
定义 RandX.hpp:316
constexpr Xoshiro256StarStar(std::uint64_t seed=DefaultSeed) noexcept
以指定种子构造引擎
定义 RandX.hpp:1099
constexpr void deserialize(state_type state) noexcept
从状态恢复引擎
定义 RandX.hpp:1210
ChaCha20(const ChaCha20 &)=delete
constexpr Xoshiro128StarStar(std::uint64_t seed=DefaultSeed) noexcept
以指定种子构造引擎
定义 RandX.hpp:1337
static constexpr result_type max() noexcept
输出范围上界
定义 RandX.hpp:1585
constexpr void discard(unsigned long long n) noexcept
跳过 n 个输出
定义 RandX.hpp:1603
ChaCha20()
构造方式 1:从 OS 熵自动播种(密码学安全,默认)
定义 RandX.hpp:1798
std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const Engine &engine)
定义 RandX.hpp:999
std::array< std::uint32_t, 2 > state_type
状态类型(2×uint32)
定义 RandX.hpp:472
constexpr state_type serialize() const noexcept
序列化引擎状态
定义 RandX.hpp:1448
std::uint32_t result_type
输出类型
定义 RandX.hpp:473
static constexpr result_type max() noexcept
输出范围上界
定义 RandX.hpp:1443
std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &is, Engine &engine)
定义 RandX.hpp:1015
constexpr result_type operator()() noexcept
生成下一个 32 位随机数
定义 RandX.hpp:1365
constexpr result_type operator()() noexcept
生成下一个 64 位随机数
定义 RandX.hpp:1049
constexpr void jump() noexcept
前进 2^64 步,用于创建并行子序列
定义 RandX.hpp:1378
constexpr result_type operator()() noexcept
生成下一个 64 位随机数
定义 RandX.hpp:1248
static constexpr result_type min() noexcept
输出范围下界
定义 RandX.hpp:1510
static constexpr result_type min() noexcept
输出范围下界
定义 RandX.hpp:1070
constexpr void longJump() noexcept
前进 2^192 步,用于创建更稀疏的并行子序列
定义 RandX.hpp:1165
constexpr void discard(unsigned long long n) noexcept
跳过 n 个输出
定义 RandX.hpp:1090
static constexpr result_type max() noexcept
输出范围上界
定义 RandX.hpp:1312
constexpr SplitMix64(state_type state=DefaultSeed) noexcept
以指定状态构造引擎
定义 RandX.hpp:1037
static constexpr result_type max() noexcept
输出范围上界
定义 RandX.hpp:1652
constexpr double DoubleFromBits(Uint64 i) noexcept
定义 RandX.hpp:759
std::uint64_t result_type
输出类型
定义 RandX.hpp:239
constexpr Xoroshiro128StarStar(std::uint64_t seed=DefaultSeed) noexcept
以指定种子构造引擎
定义 RandX.hpp:1225
ChaCha20 & operator=(const ChaCha20 &)=delete
std::array< std::uint32_t, 4 > state_type
状态类型(4×uint32)
定义 RandX.hpp:394
Xoshiro256StarStar & DefaultEngine()
定义 RandX.hpp:1704
constexpr state_type serialize() const noexcept
序列化引擎状态
定义 RandX.hpp:1205
void discard(unsigned long long n)
跳过 n 个输出
定义 RandX.hpp:1956
constexpr result_type operator()() noexcept
生成下一个 64 位随机数
定义 RandX.hpp:1571
constexpr result_type operator()() noexcept
生成下一个 64 位随机数
定义 RandX.hpp:1639
static constexpr result_type min() noexcept
输出范围下界
定义 RandX.hpp:1195
constexpr void deserialize(state_type state) noexcept
从状态恢复引擎
定义 RandX.hpp:1662
constexpr state_type serialize() const noexcept
序列化引擎状态
定义 RandX.hpp:1520
constexpr SFC64(std::uint64_t seed=DefaultSeed) noexcept
以指定种子构造引擎
定义 RandX.hpp:1541
static constexpr result_type min() noexcept
输出范围下界
定义 RandX.hpp:1580
std::array< std::uint64_t, 4 > state_type
状态类型(4×uint64)
定义 RandX.hpp:238
std::uint64_t result_type
输出类型
定义 RandX.hpp:169
std::array< std::uint64_t, 4 > state_type
状态类型(4×uint64)
定义 RandX.hpp:540
std::uint64_t RandomSeed()
生成非确定性的 64 位种子
定义 RandX.hpp:1683
constexpr result_type operator()() noexcept
生成下一个 64 位随机数
定义 RandX.hpp:1122
void reseed()
从 OS 熵重新播种
定义 RandX.hpp:1914
constexpr float FloatFromBits(Uint32 i) noexcept
定义 RandX.hpp:753
constexpr void deserialize(state_type state) noexcept
从状态恢复引擎
定义 RandX.hpp:1085
constexpr Xoroshiro64StarStar(std::uint64_t seed=DefaultSeed) noexcept
以指定种子构造引擎
定义 RandX.hpp:1468
constexpr void deserialize(state_type state) noexcept
从状态恢复引擎
定义 RandX.hpp:1322
std::uint64_t result_type
输出类型
定义 RandX.hpp:683
constexpr void jump() noexcept
前进 2^64 步,用于创建并行子序列
定义 RandX.hpp:1259
std::uint32_t result_type
输出类型
定义 RandX.hpp:395
std::uint64_t result_type
输出类型
定义 RandX.hpp:317
constexpr void deserialize(state_type state) noexcept
从状态恢复引擎
定义 RandX.hpp:1595
constexpr void deserialize(state_type state) noexcept
从状态恢复引擎
定义 RandX.hpp:1525
constexpr state_type serialize() const noexcept
序列化引擎状态
定义 RandX.hpp:1590
constexpr void discard(unsigned long long n) noexcept
跳过 n 个输出
定义 RandX.hpp:1669
std::uint64_t result_type
输出类型
定义 RandX.hpp:541
constexpr void discard(unsigned long long n) noexcept
跳过 n 个输出
定义 RandX.hpp:1459
std::uint64_t state_type
状态类型(1×uint64)
定义 RandX.hpp:168
static constexpr result_type max() noexcept
输出范围上界
定义 RandX.hpp:732
constexpr void deserialize(state_type state) noexcept
从状态恢复引擎
定义 RandX.hpp:1453
static constexpr result_type max() noexcept
输出范围上界
定义 RandX.hpp:1075
static constexpr result_type min() noexcept
输出范围下界
定义 RandX.hpp:1647
std::uint64_t result_type
输出类型
定义 RandX.hpp:612
static constexpr result_type max() noexcept
输出范围上界
定义 RandX.hpp:1515
~ChaCha20() noexcept
定义 RandX.hpp:1791
static constexpr result_type max() noexcept
输出范围上界
定义 RandX.hpp:1200
constexpr state_type serialize() const noexcept
序列化引擎状态
定义 RandX.hpp:1317
constexpr void longJump() noexcept
前进 2^96 步,用于创建更稀疏的并行子序列
定义 RandX.hpp:1408
constexpr void discard(unsigned long long n) noexcept
跳过 n 个输出
定义 RandX.hpp:1531
constexpr void discard(unsigned long long n) noexcept
跳过 n 个输出
定义 RandX.hpp:1216
constexpr void discard(unsigned long long n) noexcept
跳过 n 个输出
定义 RandX.hpp:1328
T RandChiSquared(T n=T{1})
生成卡方分布随机数
定义 RandX.hpp:3132
std::string RandString(std::size_t length, std::string_view charset="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
生成指定长度的随机字符串
定义 RandX.hpp:2847
T RandExtremeValue(T a=T{0}, T b=T{1})
生成极值分布(Gumbel)随机数
定义 RandX.hpp:3106
T RandFisherF(T m=T{1}, T n=T{1})
生成 Fisher F 分布随机数
定义 RandX.hpp:3183
T RandCauchy(T a=T{0}, T b=T{1})
生成柯西分布随机数
定义 RandX.hpp:3052
T RandStudentT(T n=T{1})
生成学生 t 分布随机数
定义 RandX.hpp:3157
T RandGamma(T alpha=T{1}, T beta=T{1})
生成伽马分布随机数
定义 RandX.hpp:2946
T RandWeibull(T a=T{1}, T b=T{1})
生成韦布尔分布随机数
定义 RandX.hpp:3079
T RandExp(T lambda=T{1})
生成指数分布随机数
定义 RandX.hpp:2893
T RandLogNormal(T mean=T{0}, T stddev=T{1})
生成对数正态分布随机数
定义 RandX.hpp:3000
T RandBeta(T a=T{1}, T b=T{1})
生成 Beta 分布随机数
定义 RandX.hpp:3211
constexpr Engine MakeStreamEngine(std::uint64_t streamId, std::uint64_t seed=DefaultSeed)
从同一种子创建第 streamId 个不重叠子序列的引擎
定义 RandX.hpp:3308
T RandBinomial(T t=1, double p=0.5)
生成二项分布随机数
定义 RandX.hpp:2973
T RandGeometric(double p=0.5)
生成几何分布随机数(首次成功前的失败次数)
定义 RandX.hpp:3026
T RandPoisson(double mean=1.0)
生成泊松分布随机数
定义 RandX.hpp:2918
std::string RandUUID(Engine &engine)
生成随机 UUID v4 字符串
定义 RandX.hpp:3266
bool GetOsEntropyBytes(void *buf, std::size_t n) noexcept
定义 RandX.hpp:832
constexpr std::uint32_t ChaCha20Constants[4]
定义 RandX.hpp:894
constexpr bool is_rand_fillable_v
定义 RandX_Cpp17.hpp:1707
bool HardwareRand64(std::uint64_t &out) noexcept
定义 RandX.hpp:804
constexpr bool is_serializable_engine_v
定义 RandX_Cpp17.hpp:1743
constexpr std::uint64_t ChaCha20ReseedThreshold
定义 RandX.hpp:899
static void ChaCha20QuarterRound(std::uint32_t &a, std::uint32_t &b, std::uint32_t &c, std::uint32_t &d) noexcept
定义 RandX.hpp:902
constexpr bool is_random_access_iterator_v
定义 RandX_Cpp17.hpp:1661
constexpr bool is_input_iterator_v
定义 RandX_Cpp17.hpp:1665
constexpr bool is_character_v
定义 RandX_Cpp17.hpp:1638
std::uint64_t Generate64Bits(Engine &engine)
定义 RandX.hpp:913
static constexpr std::uint64_t RotL(const std::uint64_t x, const int s) noexcept
定义 RandX.hpp:767
static constexpr bool IsAllZero(const std::array< std::uint64_t, N > &state) noexcept
定义 RandX.hpp:788
bool HasCryptoGradeOsEntropy() noexcept
定义 RandX.hpp:883
constexpr bool is_random_access_container_v
定义 RandX_Cpp17.hpp:1679
static void SecureWipe(void *ptr, std::size_t len) noexcept
定义 RandX.hpp:779
constexpr std::uint64_t HashSetThresholdK
定义 RandX.hpp:2493
constexpr bool is_indexable_state_v
定义 RandX_Cpp17.hpp:1723
constexpr std::uint64_t DefaultSeed
定义 RandX.hpp:140