98# include <type_traits>
101# include <string_view>
102# include <unordered_set>
109# if defined(_MSC_VER) && (defined(__x86_64__) || defined(_M_X64))
110# include <immintrin.h>
113# if defined(_WIN32) && __has_include(<bcrypt.h>)
116# ifndef WIN32_LEAN_AND_MEAN
117# define WIN32_LEAN_AND_MEAN
124# pragma comment(lib, "bcrypt.lib")
126# if(defined(__MINGW32__) || defined(__MINGW64__)) && !defined(RANDX_SUPPRESS_LINK_HINT)
127# pragma message("RandX: MinGW 需手动链接 bcrypt(编译命令添加 -lbcrypt)")
129# elif defined(__linux__) && __has_include(<sys/random.h>)
130# include <sys/random.h>
132# elif defined(__APPLE__) && __has_include(<Security/Security.h>)
133# include <Security/Security.h>
143 template <std::same_as<std::u
int32_t> U
int32>
148 template <std::same_as<std::u
int64_t> U
int64>
178 template <
class SeedSeq>
179 requires (!std::same_as<std::remove_cvref_t<SeedSeq>,
SplitMix64>)
189 constexpr
void discard(
unsigned long long n) noexcept;
194 template <std::
size_t N>
248 template <
class SeedSeq>
264 constexpr
void discard(
unsigned long long n) noexcept;
269 constexpr
void jump() noexcept;
326 template <
class SeedSeq>
342 constexpr
void discard(
unsigned long long n) noexcept;
347 constexpr
void jump() noexcept;
404 template <
class SeedSeq>
420 constexpr
void discard(
unsigned long long n) noexcept;
425 constexpr
void jump() noexcept;
482 template <
class SeedSeq>
498 constexpr
void discard(
unsigned long long n) noexcept;
550 template <
class SeedSeq>
551 requires (!std::same_as<std::remove_cvref_t<SeedSeq>,
SFC64>)
553 explicit constexpr SFC64(SeedSeq& seq);
566 constexpr
void discard(
unsigned long long n) noexcept;
589 friend auto operator <=>(const
SFC64&, const
SFC64&) = default;
596 std::uint64_t m_counter;
621 template <
class SeedSeq>
622 requires (!std::same_as<std::remove_cvref_t<SeedSeq>,
RomuDuoJr>)
624 explicit constexpr RomuDuoJr(SeedSeq& seq);
637 constexpr
void discard(
unsigned long long n) noexcept;
699 explicit
ChaCha20(std::uint64_t seed);
708 ChaCha20(const std::uint8_t* key, std::
size_t keyLen,
709 const std::uint8_t* nonce, std::
size_t nonceLen,
710 std::uint32_t counter = 0);
718 void discard(
unsigned long long n);
738 std::array<std::uint32_t, 12> m_state;
739 std::array<std::uint8_t, 64> m_buffer;
740 std::size_t m_bufferPos;
741 std::uint64_t m_bytesSinceReseed;
743 void generateBlock();
744 void reseedIfNecessary();
752 template <std::same_as<std::u
int32_t> U
int32>
755 return (i >> 8) * 0x1.0p-24f;
758 template <std::same_as<std::u
int64_t> U
int64>
761 return (i >> 11) * 0x1.0p-53;
767 static constexpr std::uint64_t
RotL(
const std::uint64_t x,
const int s)
noexcept
769 return std::rotl(x, s);
773 static constexpr std::uint32_t
RotL(
const std::uint32_t x,
const int s)
noexcept
775 return std::rotl(x, s);
781 volatile auto* p =
static_cast<volatile std::uint8_t*
>(ptr);
782 while (len--) *p++ = 0;
786 template <std::
size_t N>
788 static constexpr bool IsAllZero(
const std::array<std::uint64_t, N>& state)
noexcept
790 for (
const auto& s : state) {
if (s != 0)
return false; }
794 template <std::
size_t N>
796 static constexpr bool IsAllZero(
const std::array<std::uint32_t, N>& state)
noexcept
798 for (
const auto& s : state) {
if (s != 0)
return false; }
806#if defined(__x86_64__) || defined(_M_X64)
807 #if defined(__RDRND__)
808 unsigned long long result;
809 if (__builtin_ia32_rdrand64_step(&result))
814 #elif defined(_MSC_VER)
815 unsigned long long result;
816 if (_rdrand64_step(&result))
834 if (n == 0)
return true;
835 auto* p =
static_cast<std::uint8_t*
>(buf);
837# if defined(_WIN32) && __has_include(<bcrypt.h>)
840 std::size_t filled = 0;
843 const ULONG chunkSize =
static_cast<ULONG
>((std::min)(n - filled,
static_cast<std::size_t
>((std::numeric_limits<ULONG>::max)())));
844 if (::BCryptGenRandom(
nullptr, p + filled, chunkSize, BCRYPT_USE_SYSTEM_PREFERRED_RNG) < 0)
852# elif defined(__linux__) && __has_include(<sys/random.h>)
854 std::size_t filled = 0;
857 const ssize_t ret = ::getrandom(p + filled, n - filled, 0);
860 if (errno == EINTR)
continue;
863 if (ret == 0)
return false;
864 filled +=
static_cast<std::size_t
>(ret);
868# elif defined(__APPLE__) && __has_include(<Security/Security.h>)
870 return (::SecRandomCopyBytes(kSecRandomDefault, n, p) == errSecSuccess);
885# if (defined(_WIN32) && __has_include(<bcrypt.h>)) || (defined(__linux__) && __has_include(<sys/random.h>)) || (defined(__APPLE__) && __has_include(<Security/Security.h>))
895 0x61707865u, 0x3320646eu, 0x79622d32u, 0x6b206574u
903 std::uint32_t& c, std::uint32_t& d)
noexcept
905 a += b; d ^= a; d =
RotL(d, 16);
906 c += d; b ^= c; b =
RotL(b, 12);
907 a += b; d ^= a; d =
RotL(d, 8);
908 c += d; b ^= c; b =
RotL(b, 7);
911 template <
class Engine>
915 if constexpr (
sizeof(
typename Engine::result_type) >= 8)
917 return static_cast<std::uint64_t
>(engine());
921 const std::uint64_t lo =
static_cast<std::uint64_t
>(engine());
922 const std::uint64_t hi =
static_cast<std::uint64_t
>(engine());
923 return (hi << 32) | lo;
931 std::same_as<T, char> ||
932 std::same_as<T, wchar_t> ||
933 std::same_as<T, char16_t> ||
934 std::same_as<T, char32_t>
935#if defined(__cpp_char8_t) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
936 || std::same_as<T, char8_t>
943 { cs.size() } -> std::same_as<std::size_t>;
944 { s[std::size_t{}] } -> std::same_as<typename S::value_type&>;
950 { ce.serialize() } -> std::same_as<typename E::state_type>;
951 { e.deserialize(std::declval<typename E::state_type>()) } -> std::same_as<void>;
952 typename E::state_type;
966 { e.jump() } -> std::same_as<void>;
983 template <
class It,
class T>
985 && (std::integral<T> || std::floating_point<T>);
997 template <
class CharT,
class Traits, detail::SerializableEngine Engine>
998 std::basic_ostream<CharT, Traits>&
999 operator<<(std::basic_ostream<CharT, Traits>& os,
const Engine& engine)
1001 auto state = engine.serialize();
1002 for (std::size_t i = 0; i < state.size(); ++i)
1004 if (i != 0) os <<
' ';
1013 template <
class CharT,
class Traits, detail::SerializableEngine Engine>
1014 std::basic_istream<CharT, Traits>&
1015 operator>>(std::basic_istream<CharT, Traits>& is, Engine& engine)
1017 typename Engine::state_type state{};
1019 for (; i < state.size() && is; ++i)
1022 if (i == state.size() && is)
1024 engine.deserialize(state);
1028 is.setstate(std::ios_base::failbit);
1040 template <
class SeedSeq>
1041 requires (!std::same_as<std::remove_cvref_t<SeedSeq>,
SplitMix64>)
1044 std::array<std::uint32_t, 2> seeds;
1045 seq.generate(seeds.begin(), seeds.end());
1046 m_state = (
static_cast<std::uint64_t
>(seeds[0]) << 32) | seeds[1];
1051 std::uint64_t z = (m_state += 0x9e3779b97f4a7c15);
1052 z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
1053 z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
1054 return z ^ (z >> 31);
1057 template <std::
size_t N>
1060 std::array<std::uint64_t, N> seeds = {};
1062 for (
auto& seed : seeds)
1072 return std::numeric_limits<result_type>::lowest();
1077 return std::numeric_limits<result_type>::max();
1092 for (
unsigned long long i = 0; i < n; ++i) {
operator()(); }
1105 template <
class SeedSeq>
1106 requires (!std::same_as<std::remove_cvref_t<SeedSeq>, Xoshiro256StarStar>)
1109 std::array<std::uint32_t, 8> seeds;
1110 seq.generate(seeds.begin(), seeds.end());
1111 for (
int i = 0; i < 4; ++i)
1112 m_state[i] = (
static_cast<std::uint64_t
>(seeds[2*i]) << 32) | seeds[2*i+1];
1124 const std::uint64_t result =
detail::RotL(m_state[1] * 5, 7) * 9;
1125 const std::uint64_t t = m_state[1] << 17;
1126 m_state[2] ^= m_state[0];
1127 m_state[3] ^= m_state[1];
1128 m_state[1] ^= m_state[2];
1129 m_state[0] ^= m_state[3];
1137 constexpr std::uint64_t JUMP[] = { 0x180ec6d33cfd0aba, 0xd5a61266f0c9392c, 0xa9582618e03fc9aa, 0x39abdc4529b1661c };
1139 std::uint64_t s0 = 0;
1140 std::uint64_t s1 = 0;
1141 std::uint64_t s2 = 0;
1142 std::uint64_t s3 = 0;
1144 for (std::uint64_t j : JUMP)
1146 for (
int b = 0; b < 64; ++b)
1148 if (j & UINT64_C(1) << b)
1167 constexpr std::uint64_t LONG_JUMP[] = { 0x76e15d3efefdcbbf, 0xc5004e441c522fb3, 0x77710069854ee241, 0x39109bb02acbe635 };
1169 std::uint64_t s0 = 0;
1170 std::uint64_t s1 = 0;
1171 std::uint64_t s2 = 0;
1172 std::uint64_t s3 = 0;
1174 for (std::uint64_t j : LONG_JUMP)
1176 for (
int b = 0; b < 64; ++b)
1178 if (j & UINT64_C(1) << b)
1197 return std::numeric_limits<result_type>::lowest();
1202 return std::numeric_limits<result_type>::max();
1218 for (
unsigned long long i = 0; i < n; ++i) {
operator()(); }
1231 template <
class SeedSeq>
1232 requires (!std::same_as<std::remove_cvref_t<SeedSeq>, Xoroshiro128StarStar>)
1235 std::array<std::uint32_t, 4> seeds;
1236 seq.generate(seeds.begin(), seeds.end());
1237 m_state[0] = (
static_cast<std::uint64_t
>(seeds[0]) << 32) | seeds[1];
1238 m_state[1] = (
static_cast<std::uint64_t
>(seeds[2]) << 32) | seeds[3];
1250 const std::uint64_t s0 = m_state[0];
1251 std::uint64_t s1 = m_state[1];
1252 const std::uint64_t result =
detail::RotL(s0 * 5, 7) * 9;
1261 constexpr std::uint64_t JUMP[] = { 0xdf900294d8f554a5, 0x170865df4b3201fc };
1263 std::uint64_t s0 = 0;
1264 std::uint64_t s1 = 0;
1266 for (std::uint64_t j : JUMP)
1268 for (
int b = 0; b < 64; ++b)
1270 if (j & UINT64_C(1) << b)
1285 constexpr std::uint64_t LONG_JUMP[] = { 0xd2a98b26625eee7b, 0xdddf9b1090aa7ac1 };
1287 std::uint64_t s0 = 0;
1288 std::uint64_t s1 = 0;
1290 for (std::uint64_t j : LONG_JUMP)
1292 for (
int b = 0; b < 64; ++b)
1294 if (j & UINT64_C(1) << b)
1309 return std::numeric_limits<result_type>::lowest();
1314 return std::numeric_limits<result_type>::max();
1330 for (
unsigned long long i = 0; i < n; ++i) {
operator()(); }
1342 for (
auto& state : m_state)
1344 state =
static_cast<std::uint32_t
>(splitmix());
1349 template <
class SeedSeq>
1353 std::array<std::uint32_t, 4> seeds;
1354 seq.generate(seeds.begin(), seeds.end());
1367 const std::uint32_t result =
detail::RotL(m_state[1] * 5, 7) * 9;
1368 const std::uint32_t t = m_state[1] << 9;
1369 m_state[2] ^= m_state[0];
1370 m_state[3] ^= m_state[1];
1371 m_state[1] ^= m_state[2];
1372 m_state[0] ^= m_state[3];
1380 constexpr std::uint32_t JUMP[] = { 0x8764000b, 0xf542d2d3, 0x6fa035c3, 0x77f2db5b };
1382 std::uint32_t s0 = 0;
1383 std::uint32_t s1 = 0;
1384 std::uint32_t s2 = 0;
1385 std::uint32_t s3 = 0;
1387 for (std::uint32_t j : JUMP)
1389 for (
int b = 0; b < 32; ++b)
1391 if (j & UINT32_C(1) << b)
1410 constexpr std::uint32_t LONG_JUMP[] = { 0xb523952e, 0x0b6f099f, 0xccf5a0ef, 0x1c580662 };
1412 std::uint32_t s0 = 0;
1413 std::uint32_t s1 = 0;
1414 std::uint32_t s2 = 0;
1415 std::uint32_t s3 = 0;
1417 for (std::uint32_t j : LONG_JUMP)
1419 for (
int b = 0; b < 32; ++b)
1421 if (j & UINT32_C(1) << b)
1440 return std::numeric_limits<result_type>::lowest();
1445 return std::numeric_limits<result_type>::max();
1461 for (
unsigned long long i = 0; i < n; ++i) {
operator()(); }
1473 for (
auto& state : m_state)
1475 state =
static_cast<std::uint32_t
>(splitmix());
1480 template <
class SeedSeq>
1484 std::array<std::uint32_t, 2> seeds;
1485 seq.generate(seeds.begin(), seeds.end());
1498 const std::uint32_t s0 = m_state[0];
1499 std::uint32_t s1 = m_state[1];
1501 const std::uint32_t result =
detail::RotL(s0 * 0x9E3779BB, 5) * 5;
1512 return std::numeric_limits<result_type>::lowest();
1517 return std::numeric_limits<result_type>::max();
1533 for (
unsigned long long i = 0; i < n; ++i) {
operator()(); }
1542 : m_a(0), m_b(0), m_c(0), m_counter(1)
1549 for (
int i = 0; i < 12; ++i) {
operator()(); }
1552 template <
class SeedSeq>
1553 requires (!std::same_as<std::remove_cvref_t<SeedSeq>,
SFC64>)
1557 std::array<std::uint32_t, 8> seeds;
1558 seq.generate(seeds.begin(), seeds.end());
1559 m_a = (
static_cast<std::uint64_t
>(seeds[0]) << 32) | seeds[1];
1560 m_b = (
static_cast<std::uint64_t
>(seeds[2]) << 32) | seeds[3];
1561 m_c = (
static_cast<std::uint64_t
>(seeds[4]) << 32) | seeds[5];
1563 if ((m_a | m_b | m_c) == 0) m_a = 0x9E3779B97F4A7C15ULL;
1565 for (
int i = 0; i < 12; ++i) {
operator()(); }
1569 : m_a(state[0]), m_b(state[1]), m_c(state[2]), m_counter(state[3]) {}
1573 const std::uint64_t tmp = m_a + m_b + m_counter++;
1574 m_a = m_b ^ (m_b >> 11);
1575 m_b = m_c + (m_c << 3);
1582 return std::numeric_limits<result_type>::lowest();
1587 return std::numeric_limits<result_type>::max();
1592 return { m_a, m_b, m_c, m_counter };
1600 m_counter = state[3];
1605 for (
unsigned long long i = 0; i < n; ++i) {
operator()(); }
1619 if (m_x == 0 && m_y == 0) { m_x = 1; }
1622 template <
class SeedSeq>
1623 requires (!std::same_as<std::remove_cvref_t<SeedSeq>,
RomuDuoJr>)
1626 std::array<std::uint32_t, 4> seeds;
1627 seq.generate(seeds.begin(), seeds.end());
1628 m_x = (
static_cast<std::uint64_t
>(seeds[0]) << 32) | seeds[1];
1629 m_y = (
static_cast<std::uint64_t
>(seeds[2]) << 32) | seeds[3];
1630 if (m_x == 0 && m_y == 0) m_x = 1;
1634 : m_x(state[0]), m_y(state[1])
1636 assert(!(m_x == 0 && m_y == 0) &&
"全零状态是吸收态,禁止使用");
1641 const std::uint64_t xp = m_x;
1642 m_x = 15241094284759029579ULL * m_y;
1649 return std::numeric_limits<result_type>::lowest();
1654 return std::numeric_limits<result_type>::max();
1659 return { m_x, m_y };
1664 assert(!(state[0] == 0 && state[1] == 0) &&
"全零状态是吸收态,禁止使用");
1671 for (
unsigned long long i = 0; i < n; ++i) {
operator()(); }
1690 std::random_device rd;
1693 return (
static_cast<std::uint64_t
>(rd()) << 32) | rd();
1698 return static_cast<std::uint64_t
>(std::chrono::system_clock::now().time_since_epoch().count());
1724 throw std::runtime_error(
"SecureRandomBytes: OS entropy source failed");
1760 : m_state(other.m_state),
1761 m_buffer(other.m_buffer),
1762 m_bufferPos(other.m_bufferPos),
1763 m_bytesSinceReseed(other.m_bytesSinceReseed)
1767 other.m_bufferPos = 64;
1768 other.m_bytesSinceReseed = 0;
1778 m_state = other.m_state;
1779 m_buffer = other.m_buffer;
1780 m_bufferPos = other.m_bufferPos;
1781 m_bytesSinceReseed = other.m_bytesSinceReseed;
1785 other.m_bufferPos = 64;
1786 other.m_bytesSinceReseed = 0;
1799 : m_state{}, m_buffer{}, m_bufferPos(64), m_bytesSinceReseed(0)
1807 : m_state{}, m_buffer{}, m_bufferPos(64), m_bytesSinceReseed(0)
1811 for (
int i = 0; i < 4; ++i)
1813 const std::uint64_t v = sm();
1814 m_state[i * 2] =
static_cast<std::uint32_t
>(v);
1815 m_state[i * 2 + 1] =
static_cast<std::uint32_t
>(v >> 32);
1819 const std::uint64_t v5 = sm();
1820 m_state[9] =
static_cast<std::uint32_t
>(v5);
1821 m_state[10] =
static_cast<std::uint32_t
>(v5 >> 32);
1823 m_state[11] =
static_cast<std::uint32_t
>(sm());
1829 const std::uint8_t* nonce, std::size_t nonceLen,
1830 const std::uint32_t counter)
1831 : m_state{}, m_buffer{}, m_bufferPos(64), m_bytesSinceReseed(0)
1834 throw std::invalid_argument(
"ChaCha20: key must be 32 bytes");
1836 throw std::invalid_argument(
"ChaCha20: nonce must be 12 bytes");
1838 for (
int i = 0; i < 8; ++i)
1840 m_state[i] =
static_cast<std::uint32_t
>(key[i * 4])
1841 | (
static_cast<std::uint32_t
>(key[i * 4 + 1]) << 8)
1842 | (
static_cast<std::uint32_t
>(key[i * 4 + 2]) << 16)
1843 | (
static_cast<std::uint32_t
>(key[i * 4 + 3]) << 24);
1846 for (
int i = 0; i < 3; ++i)
1848 m_state[9 + i] =
static_cast<std::uint32_t
>(nonce[i * 4])
1849 | (
static_cast<std::uint32_t
>(nonce[i * 4 + 1]) << 8)
1850 | (
static_cast<std::uint32_t
>(nonce[i * 4 + 2]) << 16)
1851 | (
static_cast<std::uint32_t
>(nonce[i * 4 + 3]) << 24);
1853 m_state[8] = counter;
1857 inline void ChaCha20::generateBlock()
1860 std::array<std::uint32_t, 16> state{};
1865 for (
int i = 0; i < 8; ++i) state[4 + i] = m_state[i];
1866 state[12] = m_state[8];
1867 state[13] = m_state[9];
1868 state[14] = m_state[10];
1869 state[15] = m_state[11];
1871 std::array<std::uint32_t, 16> working = state;
1874 for (
int i = 0; i < 10; ++i)
1889 for (
int i = 0; i < 16; ++i)
1891 const std::uint32_t v = working[i] + state[i];
1892 m_buffer[i * 4 + 0] =
static_cast<std::uint8_t
>(v);
1893 m_buffer[i * 4 + 1] =
static_cast<std::uint8_t
>(v >> 8);
1894 m_buffer[i * 4 + 2] =
static_cast<std::uint8_t
>(v >> 16);
1895 m_buffer[i * 4 + 3] =
static_cast<std::uint8_t
>(v >> 24);
1898 if (m_state[8] == 0xFFFFFFFFU)
1900 throw std::overflow_error(
"ChaCha20: 32-bit block counter overflow");
1907 inline void ChaCha20::reseedIfNecessary()
1916 std::array<std::uint8_t, 44> seed;
1919 for (
int i = 0; i < 8; ++i)
1921 m_state[i] =
static_cast<std::uint32_t
>(seed[i * 4])
1922 | (
static_cast<std::uint32_t
>(seed[i * 4 + 1]) << 8)
1923 | (
static_cast<std::uint32_t
>(seed[i * 4 + 2]) << 16)
1924 | (
static_cast<std::uint32_t
>(seed[i * 4 + 3]) << 24);
1927 for (
int i = 0; i < 3; ++i)
1929 m_state[9 + i] =
static_cast<std::uint32_t
>(seed[32 + i * 4])
1930 | (
static_cast<std::uint32_t
>(seed[32 + i * 4 + 1]) << 8)
1931 | (
static_cast<std::uint32_t
>(seed[32 + i * 4 + 2]) << 16)
1932 | (
static_cast<std::uint32_t
>(seed[32 + i * 4 + 3]) << 24);
1936 m_bytesSinceReseed = 0;
1944 reseedIfNecessary();
1945 if (m_bufferPos == 64)
1948 std::uint64_t result = 0;
1949 for (
int i = 0; i < 8; ++i)
1950 result |=
static_cast<std::uint64_t
>(m_buffer[m_bufferPos + i]) << (8 * i);
1952 m_bytesSinceReseed += 8;
1958 for (
unsigned long long i = 0; i < n; ++i)
operator()();
1984 template <std::
integral T =
int>
1989 std::uniform_int_distribution<T> dist(min, max);
1996 template <std::
integral T =
int>
2000 assert(max >= T{0});
2008 template <std::
floating_po
int T =
double>
2012 assert(std::isfinite(min) && std::isfinite(max) && min <= max);
2013 std::uniform_real_distribution<T> dist(min, max);
2023 assert(std::isfinite(p) && p >= 0.0 && p <= 1.0);
2024 std::bernoulli_distribution dist(p);
2032 template <
class Engine>
2036 assert(std::isfinite(p) && p >= 0.0 && p <= 1.0);
2037 std::bernoulli_distribution dist(p);
2038 return dist(engine);
2047 assert(p >= 0.0 && p <= 1.0);
2055 template <
class Engine>
2059 assert(p >= 0.0 && p <= 1.0);
2068 template <detail::Character CharT>
2073 std::uniform_int_distribution<std::int64_t> dist(
2074 static_cast<std::int64_t
>(min),
2075 static_cast<std::int64_t
>(max));
2082 template <detail::Character CharT =
char>
2094 template <detail::Character CharT,
class Engine>
2096 inline CharT
RandChar(Engine& engine, CharT min, CharT max)
2099 std::uniform_int_distribution<std::int64_t> dist(
2100 static_cast<std::int64_t
>(min),
2101 static_cast<std::int64_t
>(max));
2102 return static_cast<CharT
>(dist(engine));
2109 template <detail::Character CharT =
char,
class Engine>
2126 template <
class Container>
2127 requires std::ranges::random_access_range<Container>
2132 throw std::invalid_argument(
"RandElement: empty container");
2140 template <
class Container>
2141 requires std::ranges::random_access_range<Container>
2143 inline std::ranges::range_value_t<Container>
RandElement(Container&& c)
2146 throw std::invalid_argument(
"RandElement: empty container");
2155 template <std::random_access_iterator It>
2159 using Diff = std::iter_difference_t<It>;
2160 const Diff n = std::distance(first, last);
2162 throw std::invalid_argument(
"RandElement: empty range");
2171 template <std::input_iterator It>
2172 requires (!std::random_access_iterator<It>)
2177 throw std::invalid_argument(
"RandElement: empty range");
2178 It selected = first;
2180 for (std::iter_difference_t<It> i = 1; first != last; ++first, ++i)
2182 if (
RandInt<std::iter_difference_t<It>>(0, i) == 0)
2193 template <std::random_access_iterator It,
class Engine>
2197 using Diff = std::iter_difference_t<It>;
2198 const Diff n = std::distance(first, last);
2200 throw std::invalid_argument(
"RandElement: empty range");
2201 return std::next(first,
RandInt<Diff>(engine, Diff{0}, n - 1));
2209 template <std::input_iterator It,
class Engine>
2210 requires (!std::random_access_iterator<It>)
2215 throw std::invalid_argument(
"RandElement: empty range");
2216 It selected = first;
2218 for (std::iter_difference_t<It> i = 1; first != last; ++first, ++i)
2220 if (
RandInt<std::iter_difference_t<It>>(engine, std::iter_difference_t<It>{0}, i) == 0)
2237 template <std::
floating_po
int T =
double>
2241 assert(std::isfinite(mean) && std::isfinite(stddev) && stddev > T{0});
2242 std::normal_distribution<T> dist(mean, stddev);
2251 template <
class Engine, std::
floating_po
int T =
double>
2253 inline T
RandNormal(Engine& engine, T mean = T{0}, T stddev = T{1})
2255 assert(std::isfinite(mean) && std::isfinite(stddev) && stddev > T{0});
2256 std::normal_distribution<T> dist(mean, stddev);
2257 return dist(engine);
2262 template <std::ranges::random_access_range Container>
2275 template <
class It,
class T>
2276 requires detail::RandFillable<It, T> && std::integral<T>
2280 std::uniform_int_distribution<T> dist(min, max);
2281 for (; first != last; ++first)
2290 template <
class It, std::
floating_po
int T>
2291 requires std::output_iterator<It, T>
2295 std::uniform_real_distribution<T> dist(min, max);
2296 for (; first != last; ++first)
2306 template <
class It,
class T,
class Engine>
2307 requires detail::RandFillable<It, T> && std::integral<T>
2308 inline void RandFill(Engine& engine, It first, It last, T min, T max)
2311 std::uniform_int_distribution<T> dist(min, max);
2312 for (; first != last; ++first)
2313 *first = dist(engine);
2322 template <
class It, std::
floating_po
int T,
class Engine>
2323 requires std::output_iterator<It, T>
2324 inline void RandFill(Engine& engine, It first, It last, T min, T max)
2327 std::uniform_real_distribution<T> dist(min, max);
2328 for (; first != last; ++first)
2329 *first = dist(engine);
2337 template <std::
integral T =
int>
2344 std::uniform_int_distribution<T> dist(min, max);
2346 for (std::size_t i = 0; i < n; ++i)
2347 v.push_back(dist(engine));
2356 template <std::
floating_po
int T =
double>
2363 std::uniform_real_distribution<T> dist(min, max);
2365 for (std::size_t i = 0; i < n; ++i)
2366 v.push_back(dist(engine));
2376 template <std::
integral T =
int,
class Engine>
2378 inline std::vector<T>
RandVector(Engine& engine, T min, T max, std::size_t n)
2383 std::uniform_int_distribution<T> dist(min, max);
2384 for (std::size_t i = 0; i < n; ++i)
2385 v.push_back(dist(engine));
2395 template <std::
floating_po
int T =
double,
class Engine>
2397 inline std::vector<T>
RandVector(Engine& engine, T min, T max, std::size_t n)
2402 std::uniform_real_distribution<T> dist(min, max);
2403 for (std::size_t i = 0; i < n; ++i)
2404 v.push_back(dist(engine));
2411 template <
class WeightContainer>
2413 inline typename WeightContainer::size_type
RandWeighted(
const WeightContainer& weights)
2415 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; }));
2416 using Size =
typename WeightContainer::size_type;
2417 std::discrete_distribution<Size> dist(weights.begin(), weights.end());
2425 template <
class Engine,
class WeightContainer>
2427 inline typename WeightContainer::size_type
RandWeighted(Engine& engine,
const WeightContainer& weights)
2429 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; }));
2430 using Size =
typename WeightContainer::size_type;
2431 std::discrete_distribution<Size> dist(weights.begin(), weights.end());
2432 return dist(engine);
2438 template <
class IntType>
2449 template <
class Engine,
class IntType>
2451 inline IntType
RandWeighted(Engine& engine, std::discrete_distribution<IntType>& dist)
2453 return dist(engine);
2461 template <std::
integral T,
class Engine>
2466 std::uniform_int_distribution<T> dist(min, max);
2467 return dist(engine);
2475 template <std::
floating_po
int T,
class Engine>
2477 inline T
RandReal(Engine& engine, T min = T{0}, T max = T{1})
2479 assert(std::isfinite(min) && std::isfinite(max) && min <= max);
2480 std::uniform_real_distribution<T> dist(min, max);
2481 return dist(engine);
2490 inline constexpr std::uint64_t
BoundedRand(Xoshiro256StarStar& rng, std::uint64_t range)
noexcept;
2526 return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
2528 return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
2530 return "abcdefghijklmnopqrstuvwxyz";
2532 return "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
2534 return "0123456789";
2536 return "0123456789abcdef";
2538 return "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
2540 return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2542 return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
2556 if (charset.empty())
2557 throw std::invalid_argument(
"RandChar: charset is empty");
2559 std::uniform_int_distribution<std::size_t> dist(0, charset.size() - 1);
2560 return charset[dist(rng)];
2567 template <
class Engine>
2572 if (charset.empty())
2573 throw std::invalid_argument(
"RandChar: charset is empty");
2574 std::uniform_int_distribution<std::size_t> dist(0, charset.size() - 1);
2575 return charset[dist(engine)];
2587 template <std::ranges::random_access_range Container>
2589 inline auto RandSample(
const Container& c,
typename Container::size_type n)
2591 using T =
typename Container::value_type;
2592 using Size =
typename Container::size_type;
2593 std::vector<T> pool(c.begin(), c.end());
2594 const Size size =
static_cast<Size
>(pool.size());
2595 if (n >= size)
return pool;
2597 for (Size i = 0; i < n; ++i)
2599 std::uniform_int_distribution<Size> dist(i, size - 1);
2600 const Size j = dist(rng);
2601 auto tmp = std::move(pool[i]);
2602 pool[i] = std::move(pool[j]);
2603 pool[j] = std::move(tmp);
2621 template <std::random_access_iterator It>
2623 inline std::vector<std::iter_value_t<It>>
2626 using Diff = std::iter_difference_t<It>;
2627 using T = std::iter_value_t<It>;
2628 const Diff size = std::distance(first, last);
2629 if (n <= 0 || size == 0)
2632 return std::vector<T>(first, last);
2638 const auto sizeU =
static_cast<std::uint64_t
>(size);
2643 std::unordered_set<Diff> selected;
2644 selected.reserve(
static_cast<std::size_t
>(n));
2645 std::vector<T> result;
2646 result.reserve(
static_cast<std::size_t
>(n));
2647 while (result.size() <
static_cast<std::size_t
>(n))
2649 std::uniform_int_distribution<Diff> dist(Diff{0},
static_cast<Diff
>(sizeU - 1));
2650 const Diff idx = dist(rng);
2651 if (selected.insert(idx).second)
2652 result.push_back(first[idx]);
2658 std::vector<Diff> indices(
static_cast<std::size_t
>(size));
2659 for (Diff i = 0; i < size; ++i)
2660 indices[
static_cast<std::size_t
>(i)] = i;
2663 for (Diff i = 0; i < n; ++i)
2665 std::uniform_int_distribution<Diff> dist(i,
static_cast<Diff
>(size - 1));
2666 const Diff j = dist(rng);
2667 std::swap(indices[
static_cast<std::size_t
>(i)],
2668 indices[
static_cast<std::size_t
>(j)]);
2671 std::vector<T> result;
2672 result.reserve(
static_cast<std::size_t
>(n));
2673 for (Diff i = 0; i < n; ++i)
2674 result.push_back(first[indices[
static_cast<std::size_t
>(i)]]);
2684 template <std::input_iterator It>
2685 requires (!std::random_access_iterator<It>)
2687 inline std::vector<std::iter_value_t<It>>
2690 using Diff = std::iter_difference_t<It>;
2691 using T = std::iter_value_t<It>;
2695 std::vector<T> reservoir;
2696 reservoir.reserve(
static_cast<std::size_t
>(n));
2700 for (; i < n && first != last; ++i, ++first)
2701 reservoir.push_back(*first);
2709 for (; first != last; ++i, ++first)
2711 std::uniform_int_distribution<Diff> dist(Diff{0}, i);
2712 const Diff j = dist(rng);
2714 reservoir[
static_cast<std::size_t
>(j)] = *first;
2726 template <std::random_access_iterator It,
class Engine>
2728 inline std::vector<std::iter_value_t<It>>
2729 RandSample(Engine& engine, It first, It last, std::iter_difference_t<It> n)
2731 using Diff = std::iter_difference_t<It>;
2732 using T = std::iter_value_t<It>;
2733 const Diff size = std::distance(first, last);
2734 if (n <= 0 || size == 0)
2737 return std::vector<T>(first, last);
2739 const auto sizeU =
static_cast<std::uint64_t
>(size);
2744 std::unordered_set<Diff> selected;
2745 selected.reserve(
static_cast<std::size_t
>(n));
2746 std::vector<T> result;
2747 result.reserve(
static_cast<std::size_t
>(n));
2748 while (result.size() <
static_cast<std::size_t
>(n))
2750 const Diff idx =
RandInt<Diff>(engine, Diff{0},
static_cast<Diff
>(sizeU - 1));
2751 if (selected.insert(idx).second)
2752 result.push_back(first[idx]);
2758 std::vector<Diff> indices(
static_cast<std::size_t
>(size));
2759 for (Diff i = 0; i < size; ++i)
2760 indices[
static_cast<std::size_t
>(i)] = i;
2762 for (Diff i = 0; i < n; ++i)
2764 const Diff j =
RandInt<Diff>(engine, i,
static_cast<Diff
>(size - 1));
2765 std::swap(indices[
static_cast<std::size_t
>(i)],
2766 indices[
static_cast<std::size_t
>(j)]);
2769 std::vector<T> result;
2770 result.reserve(
static_cast<std::size_t
>(n));
2771 for (Diff i = 0; i < n; ++i)
2772 result.push_back(first[indices[
static_cast<std::size_t
>(i)]]);
2783 template <std::input_iterator It,
class Engine>
2784 requires (!std::random_access_iterator<It>)
2786 inline std::vector<std::iter_value_t<It>>
2787 RandSample(Engine& engine, It first, It last, std::iter_difference_t<It> n)
2789 using Diff = std::iter_difference_t<It>;
2790 using T = std::iter_value_t<It>;
2794 std::vector<T> reservoir;
2795 reservoir.reserve(
static_cast<std::size_t
>(n));
2798 for (; i < n && first != last; ++i, ++first)
2799 reservoir.push_back(*first);
2805 for (; first != last; ++i, ++first)
2809 reservoir[
static_cast<std::size_t
>(j)] = *first;
2820 std::vector<std::size_t> perm(n);
2821 for (std::size_t i = 0; i < n; ++i) perm[i] = i;
2822 if (n < 2)
return perm;
2824 for (std::size_t i = n - 1; i > 0; --i)
2826 std::uniform_int_distribution<std::size_t> dist(0, i);
2827 const std::size_t j = dist(rng);
2847 inline std::string
RandString(std::size_t length, std::string_view charset =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
2849 if (charset.empty())
2850 throw std::invalid_argument(
"RandString: charset is empty");
2851 std::string result(length,
'\0');
2853 std::uniform_int_distribution<std::size_t> dist(0, charset.size() - 1);
2854 for (std::size_t i = 0; i < length; ++i)
2855 result[i] = charset[dist(rng)];
2874 template <
class Engine>
2879 if (charset.empty())
2880 throw std::invalid_argument(
"RandString: charset is empty");
2881 std::string result(n,
'\0');
2882 std::uniform_int_distribution<std::size_t> dist(0, charset.size() - 1);
2883 for (std::size_t i = 0; i < n; ++i)
2884 result[i] = charset[dist(engine)];
2891 template <std::
floating_po
int T =
double>
2895 assert(std::isfinite(lambda) && lambda > T{0});
2896 std::exponential_distribution<T> dist(lambda);
2904 template <
class Engine, std::
floating_po
int T =
double>
2908 assert(std::isfinite(lambda) && lambda > T{0});
2909 std::exponential_distribution<T> dist(lambda);
2910 return dist(engine);
2916 template <std::
integral T =
int>
2920 assert(std::isfinite(mean) && mean >= 0.0);
2921 if (mean == 0.0)
return T{0};
2922 std::poisson_distribution<T> dist(mean);
2930 template <
class Engine, std::
integral T =
int>
2934 assert(std::isfinite(mean) && mean >= 0.0);
2935 if (mean == 0.0)
return T{0};
2936 std::poisson_distribution<T> dist(mean);
2937 return dist(engine);
2944 template <std::
floating_po
int T =
double>
2948 assert(std::isfinite(alpha) && std::isfinite(beta) && alpha > T{0} && beta > T{0});
2949 std::gamma_distribution<T> dist(alpha, beta);
2958 template <
class Engine, std::
floating_po
int T =
double>
2960 inline T
RandGamma(Engine& engine, T alpha = T{1}, T beta = T{1})
2962 assert(std::isfinite(alpha) && std::isfinite(beta) && alpha > T{0} && beta > T{0});
2963 std::gamma_distribution<T> dist(alpha, beta);
2964 return dist(engine);
2971 template <std::
integral T =
int>
2975 assert(t >= 0 && std::isfinite(p) && p >= 0.0 && p <= 1.0);
2976 std::binomial_distribution<T> dist(t, p);
2985 template <std::
integral T =
int,
class Engine>
2989 assert(t >= 0 && std::isfinite(p) && p >= 0.0 && p <= 1.0);
2990 std::binomial_distribution<T> dist(t, p);
2991 return dist(engine);
2998 template <std::
floating_po
int T =
double>
3002 assert(std::isfinite(mean) && std::isfinite(stddev) && stddev > T{0});
3003 std::lognormal_distribution<T> dist(mean, stddev);
3012 template <std::
floating_po
int T =
double,
class Engine>
3016 assert(std::isfinite(mean) && std::isfinite(stddev) && stddev > T{0});
3017 std::lognormal_distribution<T> dist(mean, stddev);
3018 return dist(engine);
3024 template <std::
integral T =
int>
3028 assert(p > 0.0 && p <= 1.0);
3029 std::geometric_distribution<T> dist(p);
3037 template <std::
integral T =
int,
class Engine>
3041 assert(p > 0.0 && p <= 1.0);
3042 std::geometric_distribution<T> dist(p);
3043 return dist(engine);
3050 template <std::
floating_po
int T =
double>
3054 assert(std::isfinite(a) && std::isfinite(b) && b > T{0});
3055 std::cauchy_distribution<T> dist(a, b);
3064 template <std::
floating_po
int T =
double,
class Engine>
3068 assert(std::isfinite(a) && std::isfinite(b) && b > T{0});
3069 std::cauchy_distribution<T> dist(a, b);
3070 return dist(engine);
3077 template <std::
floating_po
int T =
double>
3081 assert(std::isfinite(a) && std::isfinite(b) && a > T{0} && b > T{0});
3082 std::weibull_distribution<T> dist(a, b);
3091 template <std::
floating_po
int T =
double,
class Engine>
3095 assert(std::isfinite(a) && std::isfinite(b) && a > T{0} && b > T{0});
3096 std::weibull_distribution<T> dist(a, b);
3097 return dist(engine);
3104 template <std::
floating_po
int T =
double>
3108 assert(std::isfinite(a) && std::isfinite(b) && b > T{0});
3109 std::extreme_value_distribution<T> dist(a, b);
3118 template <std::
floating_po
int T =
double,
class Engine>
3122 assert(std::isfinite(a) && std::isfinite(b) && b > T{0});
3123 std::extreme_value_distribution<T> dist(a, b);
3124 return dist(engine);
3130 template <std::
floating_po
int T =
double>
3134 assert(std::isfinite(n) && n > T{0});
3135 std::chi_squared_distribution<T> dist(n);
3143 template <std::
floating_po
int T =
double,
class Engine>
3147 assert(std::isfinite(n) && n > T{0});
3148 std::chi_squared_distribution<T> dist(n);
3149 return dist(engine);
3155 template <std::
floating_po
int T =
double>
3159 assert(std::isfinite(n) && n > T{0});
3160 std::student_t_distribution<T> dist(n);
3168 template <std::
floating_po
int T =
double,
class Engine>
3172 assert(std::isfinite(n) && n > T{0});
3173 std::student_t_distribution<T> dist(n);
3174 return dist(engine);
3181 template <std::
floating_po
int T =
double>
3185 assert(std::isfinite(m) && std::isfinite(n) && m > T{0} && n > T{0});
3186 std::fisher_f_distribution<T> dist(m, n);
3195 template <std::
floating_po
int T =
double,
class Engine>
3199 assert(std::isfinite(m) && std::isfinite(n) && m > T{0} && n > T{0});
3200 std::fisher_f_distribution<T> dist(m, n);
3201 return dist(engine);
3209 template <std::
floating_po
int T =
double>
3213 assert(std::isfinite(a) && std::isfinite(b) && a > T{0} && b > T{0});
3214 std::gamma_distribution<T> distA(a, T{1});
3215 std::gamma_distribution<T> distB(b, T{1});
3217 const T x = distA(rng);
3218 const T y = distB(rng);
3219 const T sum = x + y;
3221 return RandBool(rng,
static_cast<double>(a) /
static_cast<double>(a + b)) ? T{1} : T{0};
3230 template <std::
floating_po
int T =
double,
class Engine>
3232 inline T
RandBeta(Engine& engine, T a = T{1}, T b = T{1})
3234 assert(std::isfinite(a) && std::isfinite(b) && a > T{0} && b > T{0});
3235 std::gamma_distribution<T> distA(a, T{1});
3236 std::gamma_distribution<T> distB(b, T{1});
3237 const T x = distA(engine);
3238 const T y = distB(engine);
3239 const T sum = x + y;
3241 return RandBool(engine,
static_cast<double>(a) /
static_cast<double>(a + b)) ? T{1} : T{0};
3248 template <
int N, std::
integral T = std::u
int64_t>
3249 requires (N > 0 && N <= 64 && N <= std::numeric_limits<T>::digits)
3254 if constexpr (N == 64)
3255 return static_cast<T
>(rng());
3257 return static_cast<T
>(rng() & ((std::uint64_t{1} << N) - 1));
3264 template <
class Engine>
3268 static constexpr char hex[] =
"0123456789abcdef";
3269 std::string uuid(36,
'-');
3273 for (
int i = 0; i < 8; ++i)
3274 uuid[i] = hex[(u1 >> (i * 4)) & 0xFU];
3275 for (
int i = 0; i < 4; ++i)
3276 uuid[9 + i] = hex[(u1 >> ((8 + i) * 4)) & 0xFU];
3278 for (
int i = 1; i < 4; ++i)
3279 uuid[14 + i] = hex[(u1 >> ((12 + i) * 4)) & 0xFU];
3280 uuid[19] = hex[8 + ((u2 >> 0) & 0x3U)];
3281 for (
int i = 1; i < 4; ++i)
3282 uuid[19 + i] = hex[(u2 >> (i * 4)) & 0xFU];
3283 for (
int i = 0; i < 12; ++i)
3284 uuid[24 + i] = hex[(u2 >> ((4 + i) * 4)) & 0xFU];
3305 template <
class Engine>
3306 requires detail::StreamEngine<Engine>
3311 for (std::uint64_t i = 0; i < streamId; ++i)
3323#ifdef __SIZEOF_INT128__
3327 inline constexpr std::uint64_t
BoundedRand(Xoshiro256StarStar& rng, std::uint64_t range)
noexcept
3329 if (range == 0)
return 0;
3330 __uint128_t product =
static_cast<__uint128_t
>(rng()) * range;
3331 std::uint64_t low =
static_cast<std::uint64_t
>(product);
3334 const std::uint64_t threshold = (0ULL - range) % range;
3335 while (low < threshold)
3337 product =
static_cast<__uint128_t
>(rng()) * range;
3338 low =
static_cast<std::uint64_t
>(product);
3341 return static_cast<std::uint64_t
>(product >> 64);
3348 if (range == 0)
return 0;
3349 const std::uint64_t threshold = (0ULL - range) % range;
3351 do { r = rng(); }
while (r < threshold);
3361 template <std::
integral T =
int, std::u
int64_t Seed = DefaultSeed>
3365 if (min > max)
throw std::invalid_argument(
"RandIntCE: min > max");
3367 using U = std::make_unsigned_t<T>;
3368 const U u_min =
static_cast<U
>(min);
3369 const U u_max =
static_cast<U
>(max);
3370 const U diff = u_max - u_min;
3371 if (diff == (std::numeric_limits<U>::max)())
3373 return static_cast<T
>(u_min +
static_cast<U
>(rng()));
3375 const auto range =
static_cast<std::uint64_t
>(diff) + 1;
3382 template <std::
integral T =
int, std::u
int64_t Seed = DefaultSeed>
3400 template <std::random_access_iterator It, std::u
int64_t Seed = DefaultSeed>
3403 const auto n =
static_cast<std::uint64_t
>(last - first);
3406 for (std::uint64_t i = n - 1; i > 0; --i)
3411 auto tmp = std::move(first[i]);
3412 first[i] = std::move(first[j]);
3413 first[j] = std::move(tmp);
3424 template <
class T, std::
size_t N, std::u
int64_t Seed = DefaultSeed>
3428 ShuffleCE<
decltype(arr.begin()), Seed>(arr.begin(), arr.end());
3439 static_assert(std::uniform_random_bit_generator<SplitMix64>);
3440 static_assert(std::uniform_random_bit_generator<Xoshiro256StarStar>);
3441 static_assert(std::uniform_random_bit_generator<Xoroshiro128StarStar>);
3442 static_assert(std::uniform_random_bit_generator<Xoshiro128StarStar>);
3443 static_assert(std::uniform_random_bit_generator<Xoroshiro64StarStar>);
3444 static_assert(std::uniform_random_bit_generator<SFC64>);
3445 static_assert(std::uniform_random_bit_generator<RomuDuoJr>);
3446 static_assert(std::uniform_random_bit_generator<ChaCha20>);
3458 template <std::ranges::input_range R>
3459 requires std::ranges::sized_range<R> || std::ranges::forward_range<R>
3461 inline std::ranges::range_value_t<R>
3471 template <std::ranges::input_range R>
3473 inline std::vector<std::ranges::range_value_t<R>>
3481 template <std::ranges::random_access_range R>
3482 requires std::ranges::sized_range<R>
3494 template <
class T, std::ranges::output_range<const T&> R>
3498 RandX::RandFill(std::ranges::begin(r), std::ranges::end(r), min, max);
RomuDuoJr 伪随机数生成器,64 位输出,周期估计 >= 2^51。
定义 RandX.hpp:608
SFC64(Small Fast Counter)伪随机数生成器,64 位输出,周期 >= 2^64。
定义 RandX.hpp:537
SplitMix64 伪随机数生成器,64 位输出,周期 2^64。
定义 RandX.hpp:165
Xoroshiro64** 伪随机数生成器,32 位输出,周期 2^64-1。
定义 RandX.hpp:469
Xoshiro128** 伪随机数生成器,32 位输出,周期 2^128-1。
定义 RandX.hpp:391
Xoshiro256** 伪随机数生成器,64 位输出,周期 2^256-1。
定义 RandX.hpp:235
可跳跃引擎概念:支持 jump() 前进 2^N 步
定义 RandX.hpp:965
流式引擎概念:可通过 MakeStreamEngine 创建互不重叠的子序列流
定义 RandX.hpp:980
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
std::vector< std::size_t > RandPermutation(std::size_t n)
生成 [0, n) 的随机排列
定义 RandX.hpp:2818
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
result_type operator()()
生成下一个 64 位随机数
定义 RandX.hpp:1942
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
std::string RandUUID()
定义 RandX.hpp:3290
T RandBits() noexcept
生成 N 位随机整数
定义 RandX.hpp:3251
T RandWeibull(T a=T{1}, T b=T{1})
生成韦布尔分布随机数
定义 RandX.hpp:3079
constexpr std::array< T, N > ShuffledArray(std::array< T, N > arr) noexcept
编译期洗牌数组版本(返回打乱后的副本)
定义 RandX.hpp:3426
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 T RandIntCE(T min, T max)
编译期生成 [min, max] 范围内的随机整数
定义 RandX.hpp:3363
constexpr Engine MakeStreamEngine(std::uint64_t streamId, std::uint64_t seed=DefaultSeed)
从同一种子创建第 streamId 个不重叠子序列的引擎
定义 RandX.hpp:3308
constexpr void ShuffleCE(It first, It last) noexcept
编译期 Fisher-Yates 洗牌
定义 RandX.hpp:3401
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
bool GetOsEntropyBytes(void *buf, std::size_t n) noexcept
定义 RandX.hpp:832
constexpr std::uint32_t ChaCha20Constants[4]
定义 RandX.hpp:894
bool HardwareRand64(std::uint64_t &out) noexcept
定义 RandX.hpp:804
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
std::string_view CharSetString(CharSet cs) noexcept
定义 RandX.hpp:2521
constexpr std::uint64_t BoundedRand(Xoshiro256StarStar &rng, std::uint64_t range) noexcept
定义 RandX.hpp:3346
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
static void SecureWipe(void *ptr, std::size_t len) noexcept
定义 RandX.hpp:779
constexpr std::uint64_t HashSetThresholdK
定义 RandX.hpp:2493
void RandFill(R &&r, T min, T max)
用随机数填充 range
定义 RandX.hpp:3496
std::vector< std::ranges::range_value_t< R > > RandSample(R &&r, std::ranges::range_difference_t< R > n)
无放回抽样(复用迭代器版实现,自动选择 random_access / input 路径)
定义 RandX.hpp:3474
std::ranges::range_value_t< R > RandElement(R &&r)
随机选取一个元素(返回值拷贝,非迭代器)
定义 RandX.hpp:3462
void RandShuffle(R &&r)
随机打乱 range(要求 random_access + sized)
定义 RandX.hpp:3484
constexpr std::uint64_t DefaultSeed
定义 RandX.hpp:140