RandX 1.4.3
基于 xoshiro/xoroshiro 算法族的纯头文件伪随机数生成器库
载入中...
搜索中...
未找到
RandX.hpp
浏览该文件的文档.
1//----------------------------------------------------------------------------------------
2//
3// RandX.hpp — 基于 Xoshiro 的伪随机数生成器封装库(C++23)
4//
5// 原始算法:David Blackman & Sebastiano Vigna (http://prng.di.unimi.it/)
6// 原始 C++ 封装:Ryo Suzuki (https://github.com/Reputeless/Xoshiro-cpp)
7//
8//========================================================================================
9//
10// 快速上手
11//
12// #include "RandX.hpp"
13//
14// // 最简用法:直接调用便捷函数(内部使用线程局部 Xoshiro256StarStar)
15// int dice = RandX::RandInt(1, 6); // [1, 6] 闭区间整数
16// double coin = RandX::RandReal(); // [0.0, 1.0) 浮点数
17// bool flag = RandX::RandBool(0.3); // 30% 概率为 true
18//
19// std::vector<int> v = {10, 20, 30, 40};
20// auto& elem = RandX::RandElement(v); // 随机取一个元素
21//
22// 扩展 API
23//
24// auto sample = RandX::RandSample(v, 2); // 无放回抽样 2 个
25// auto perm = RandX::RandPermutation(10); // [0,10) 随机排列
26// auto token = RandX::RandString(16); // 16 位随机字符串
27// auto uuid = RandX::RandUUID(); // UUID v4
28// auto byte = RandX::RandBits<8>(); // [0, 256) 随机整数
29// auto exp = RandX::RandExp(2.0); // 指数分布 λ=2
30// auto poi = RandX::RandPoisson(5.0); // 泊松分布 μ=5
31//
32// 手动管理引擎
33//
34// // 用真随机种子创建引擎
35// RandX::Xoshiro256StarStar rng{ RandX::RandomSeed() };
36//
37// // 指定引擎的便捷函数重载
38// int val = RandX::RandInt(rng, 0, 99);
39//
40// // 配合标准库 distribution 使用(满足 UniformRandomBitGenerator)
41// std::normal_distribution<double> norm(0.0, 1.0);
42// double sample = norm(rng);
43//
44// 多流并行
45//
46// auto s0 = RandX::MakeStreamEngine<RandX::Xoshiro256StarStar>(0);
47// auto s1 = RandX::MakeStreamEngine<RandX::Xoshiro256StarStar>(1);
48// // 各流间隔 2^128 步,互不重叠
49//
50// 编译期随机(constexpr)
51//
52// constexpr int v = RandX::RandIntCE(0, 100);
53// constexpr auto shuffled = RandX::ShuffledArray<int, 5>({1,2,3,4,5});
54//
55// 序列化 / 反序列化(保存和恢复状态)
56//
57// auto state = rng.serialize();
58// rng.deserialize(state);
59//
60// 跳跃(并行计算中生成不重叠子序列)
61//
62// rng.jump(); // 等价于前进 2^128 步(xoshiro256 系列)
63// rng.longJump(); // 等价于前进 2^192 步
64//
65// 跳过指定次数
66//
67// rng.discard(1000); // 跳过 1000 个输出
68//
69// 引擎选择指南
70//
71// 引擎 输出 周期 状态 适用场景
72// ─────────────────────────────────────────────────────────────
73// Xoshiro256StarStar 64-bit 2^256-1 32B 通用首选,统计质量最优
74// Xoroshiro128StarStar 64-bit 2^128-1 16B 内存受限,统计更优
75// Xoshiro128StarStar 32-bit 2^128-1 16B 32 位平台,统计更优
76// Xoroshiro64StarStar 32-bit 2^64-1 8B 极端内存受限
77// SplitMix64 64-bit 2^64 8B 种子扩展 / 哈希,非通用 PRNG
78// SFC64 64-bit >= 2^64 32B 速度极快,通过 PractRand
79// RomuDuoJr 64-bit >= 2^51 16B 极简极快,非关键模拟
80// ChaCha20 64-bit 无周期 48B+ 密码学安全 CSPRNG(RFC 8439)
81//
82// ⚠️ 安全声明
83// 本库的 xoshiro/xoroshiro/SFC64/RomuDuoJr 引擎均非 CSPRNG。
84// 状态可从输出逆推,不可用于密码/密钥/会话 token 等安全场景。
85// 此类场景请使用 ChaCha20 引擎或 SecureRandomBytes()。
86//
87//----------------------------------------------------------------------------------------
88
89# pragma once
90# include <cstdint>
91# include <array>
92# include <limits>
93# include <concepts>
94# include <random>
95# include <algorithm>
96# include <bit>
97# include <cassert>
98# include <type_traits>
99# include <ranges>
100# include <string>
101# include <string_view>
102# include <unordered_set>
103# include <vector>
104# include <stdexcept>
105# include <chrono> // std::chrono(RandomSeed 时间戳兜底用)
106# include <ios> // std::ios_base::failbit(流状态标志完整定义)
107# include <istream> // std::basic_istream(operator>> 所需完整类型)
108# include <ostream> // std::basic_ostream(operator<< 所需完整类型)
109# if defined(_MSC_VER) && (defined(__x86_64__) || defined(_M_X64))
110# include <immintrin.h>
111# endif
112// ── A3 跨平台 OS 熵源头文件(条件包含) ──
113# if defined(_WIN32) && __has_include(<bcrypt.h>)
114// bcrypt.h 依赖 <windows.h> 提供的 ULONG/NTSTATUS 等类型(MSVC 和 MinGW 均需)
115// NOMINMAX 阻止 <windows.h> 定义 min/max 宏(与引擎的 min()/max() 方法冲突)
116# ifndef WIN32_LEAN_AND_MEAN
117# define WIN32_LEAN_AND_MEAN
118# endif
119# ifndef NOMINMAX
120# define NOMINMAX
121# endif
122# include <windows.h>
123# include <bcrypt.h>
124# pragma comment(lib, "bcrypt.lib") // 仅 MSVC 生效
125// MinGW 不支持 #pragma comment(lib),须手动添加 -lbcrypt 链接选项
126# if(defined(__MINGW32__) || defined(__MINGW64__)) && !defined(RANDX_SUPPRESS_LINK_HINT)
127# pragma message("RandX: MinGW 需手动链接 bcrypt(编译命令添加 -lbcrypt)")
128# endif
129# elif defined(__linux__) && __has_include(<sys/random.h>)
130# include <sys/random.h>
131# include <cerrno>
132# elif defined(__APPLE__) && __has_include(<Security/Security.h>)
133# include <Security/Security.h>
134# endif
135# include <cstring> // std::memcpy(std::random_device 回退路径用)
136
137namespace RandX
138{
139 // 生成器的默认种子值
140 inline constexpr std::uint64_t DefaultSeed = 1234567890ULL;
141
142 // 将给定的 uint32 值 `i` 转换为 [0.0f, 1.0f) 范围内的 32 位浮点数
143 template <std::same_as<std::uint32_t> Uint32>
144 [[nodiscard]]
145 inline constexpr float FloatFromBits(Uint32 i) noexcept;
146
147 // 将给定的 uint64 值 `i` 转换为 [0.0, 1.0) 范围内的 64 位浮点数
148 template <std::same_as<std::uint64_t> Uint64>
149 [[nodiscard]]
150 inline constexpr double DoubleFromBits(Uint64 i) noexcept;
151
155
165 {
166 public:
167
168 using state_type = std::uint64_t;
169 using result_type = std::uint64_t;
170
173 [[nodiscard]]
174 explicit constexpr SplitMix64(state_type state = DefaultSeed) noexcept;
175
178 template <class SeedSeq>
179 requires (!std::same_as<std::remove_cvref_t<SeedSeq>, SplitMix64>)
180 [[nodiscard]]
181 explicit constexpr SplitMix64(SeedSeq& seq);
182
185 constexpr result_type operator()() noexcept;
186
189 constexpr void discard(unsigned long long n) noexcept;
190
194 template <std::size_t N>
195 [[nodiscard]]
196 constexpr std::array<std::uint64_t, N> generateSeedSequence() noexcept;
197
200 [[nodiscard]]
201 static constexpr result_type min() noexcept;
202
205 [[nodiscard]]
206 static constexpr result_type max() noexcept;
207
211 [[nodiscard]]
212 constexpr state_type serialize() const noexcept;
213
217 constexpr void deserialize(state_type state) noexcept;
218
219 friend auto operator <=>(const SplitMix64&, const SplitMix64&) = default;
220
221 private:
222
223 state_type m_state;
224 };
225
235 {
236 public:
237
238 using state_type = std::array<std::uint64_t, 4>;
239 using result_type = std::uint64_t;
240
243 [[nodiscard]]
244 explicit constexpr Xoshiro256StarStar(std::uint64_t seed = DefaultSeed) noexcept;
245
248 template <class SeedSeq>
249 requires (!std::same_as<std::remove_cvref_t<SeedSeq>, Xoshiro256StarStar>)
250 [[nodiscard]]
251 explicit constexpr Xoshiro256StarStar(SeedSeq& seq);
252
255 [[nodiscard]]
256 explicit constexpr Xoshiro256StarStar(state_type state) noexcept;
257
260 constexpr result_type operator()() noexcept;
261
264 constexpr void discard(unsigned long long n) noexcept;
265
269 constexpr void jump() noexcept;
270
274 constexpr void longJump() noexcept;
275
278 [[nodiscard]]
279 static constexpr result_type min() noexcept;
280
283 [[nodiscard]]
284 static constexpr result_type max() noexcept;
285
289 [[nodiscard]]
290 constexpr state_type serialize() const noexcept;
291
295 constexpr void deserialize(state_type state) noexcept;
296
297 friend auto operator <=>(const Xoshiro256StarStar&, const Xoshiro256StarStar&) = default;
298
299 private:
300
301 state_type m_state;
302 };
303
313 {
314 public:
315
316 using state_type = std::array<std::uint64_t, 2>;
317 using result_type = std::uint64_t;
318
321 [[nodiscard]]
322 explicit constexpr Xoroshiro128StarStar(std::uint64_t seed = DefaultSeed) noexcept;
323
326 template <class SeedSeq>
327 requires (!std::same_as<std::remove_cvref_t<SeedSeq>, Xoroshiro128StarStar>)
328 [[nodiscard]]
329 explicit constexpr Xoroshiro128StarStar(SeedSeq& seq);
330
333 [[nodiscard]]
334 explicit constexpr Xoroshiro128StarStar(state_type state) noexcept;
335
338 constexpr result_type operator()() noexcept;
339
342 constexpr void discard(unsigned long long n) noexcept;
343
347 constexpr void jump() noexcept;
348
352 constexpr void longJump() noexcept;
353
356 [[nodiscard]]
357 static constexpr result_type min() noexcept;
358
361 [[nodiscard]]
362 static constexpr result_type max() noexcept;
363
367 [[nodiscard]]
368 constexpr state_type serialize() const noexcept;
369
373 constexpr void deserialize(state_type state) noexcept;
374
375 friend auto operator <=>(const Xoroshiro128StarStar&, const Xoroshiro128StarStar&) = default;
376
377 private:
378
379 state_type m_state;
380 };
381
391 {
392 public:
393
394 using state_type = std::array<std::uint32_t, 4>;
395 using result_type = std::uint32_t;
396
399 [[nodiscard]]
400 explicit constexpr Xoshiro128StarStar(std::uint64_t seed = DefaultSeed) noexcept;
401
404 template <class SeedSeq>
405 requires (!std::same_as<std::remove_cvref_t<SeedSeq>, Xoshiro128StarStar>)
406 [[nodiscard]]
407 explicit constexpr Xoshiro128StarStar(SeedSeq& seq);
408
411 [[nodiscard]]
412 explicit constexpr Xoshiro128StarStar(state_type state) noexcept;
413
416 constexpr result_type operator()() noexcept;
417
420 constexpr void discard(unsigned long long n) noexcept;
421
425 constexpr void jump() noexcept;
426
430 constexpr void longJump() noexcept;
431
434 [[nodiscard]]
435 static constexpr result_type min() noexcept;
436
439 [[nodiscard]]
440 static constexpr result_type max() noexcept;
441
445 [[nodiscard]]
446 constexpr state_type serialize() const noexcept;
447
451 constexpr void deserialize(state_type state) noexcept;
452
453 friend auto operator <=>(const Xoshiro128StarStar&, const Xoshiro128StarStar&) = default;
454
455 private:
456
457 state_type m_state;
458 };
459
469 {
470 public:
471
472 using state_type = std::array<std::uint32_t, 2>;
473 using result_type = std::uint32_t;
474
477 [[nodiscard]]
478 explicit constexpr Xoroshiro64StarStar(std::uint64_t seed = DefaultSeed) noexcept;
479
482 template <class SeedSeq>
483 requires (!std::same_as<std::remove_cvref_t<SeedSeq>, Xoroshiro64StarStar>)
484 [[nodiscard]]
485 explicit constexpr Xoroshiro64StarStar(SeedSeq& seq);
486
489 [[nodiscard]]
490 explicit constexpr Xoroshiro64StarStar(state_type state) noexcept;
491
494 constexpr result_type operator()() noexcept;
495
498 constexpr void discard(unsigned long long n) noexcept;
499
502 [[nodiscard]]
503 static constexpr result_type min() noexcept;
504
507 [[nodiscard]]
508 static constexpr result_type max() noexcept;
509
513 [[nodiscard]]
514 constexpr state_type serialize() const noexcept;
515
519 constexpr void deserialize(state_type state) noexcept;
520
521 friend auto operator <=>(const Xoroshiro64StarStar&, const Xoroshiro64StarStar&) = default;
522
523 private:
524
525 state_type m_state;
526 };
527
536 class SFC64
537 {
538 public:
539
540 using state_type = std::array<std::uint64_t, 4>;
541 using result_type = std::uint64_t;
542
545 [[nodiscard]]
546 explicit constexpr SFC64(std::uint64_t seed = DefaultSeed) noexcept;
547
550 template <class SeedSeq>
551 requires (!std::same_as<std::remove_cvref_t<SeedSeq>, SFC64>)
552 [[nodiscard]]
553 explicit constexpr SFC64(SeedSeq& seq);
554
557 [[nodiscard]]
558 explicit constexpr SFC64(state_type state) noexcept;
559
562 constexpr result_type operator()() noexcept;
563
566 constexpr void discard(unsigned long long n) noexcept;
567
570 [[nodiscard]]
571 static constexpr result_type min() noexcept;
572
575 [[nodiscard]]
576 static constexpr result_type max() noexcept;
577
581 [[nodiscard]]
582 constexpr state_type serialize() const noexcept;
583
587 constexpr void deserialize(state_type state) noexcept;
588
589 friend auto operator <=>(const SFC64&, const SFC64&) = default;
590
591 private:
592
593 std::uint64_t m_a;
594 std::uint64_t m_b;
595 std::uint64_t m_c;
596 std::uint64_t m_counter;
597 };
598
608 {
609 public:
610
611 using state_type = std::array<std::uint64_t, 2>;
612 using result_type = std::uint64_t;
613
616 [[nodiscard]]
617 explicit constexpr RomuDuoJr(std::uint64_t seed = DefaultSeed) noexcept;
618
621 template <class SeedSeq>
622 requires (!std::same_as<std::remove_cvref_t<SeedSeq>, RomuDuoJr>)
623 [[nodiscard]]
624 explicit constexpr RomuDuoJr(SeedSeq& seq);
625
628 [[nodiscard]]
629 explicit constexpr RomuDuoJr(state_type state) noexcept;
630
633 constexpr result_type operator()() noexcept;
634
637 constexpr void discard(unsigned long long n) noexcept;
638
641 [[nodiscard]]
642 static constexpr result_type min() noexcept;
643
646 [[nodiscard]]
647 static constexpr result_type max() noexcept;
648
652 [[nodiscard]]
653 constexpr state_type serialize() const noexcept;
654
658 constexpr void deserialize(state_type state) noexcept;
659
660 friend auto operator <=>(const RomuDuoJr&, const RomuDuoJr&) = default;
661
662 private:
663
664 std::uint64_t m_x;
665 std::uint64_t m_y;
666 };
667
680 {
681 public:
682
683 using result_type = std::uint64_t;
684
685 ChaCha20(const ChaCha20&) = delete;
686 ChaCha20& operator=(const ChaCha20&) = delete;
687 ChaCha20(ChaCha20&& other) noexcept;
688 ChaCha20& operator=(ChaCha20&& other) noexcept;
689 ~ChaCha20() noexcept;
690
693 ChaCha20();
694
698 [[nodiscard]]
699 explicit ChaCha20(std::uint64_t seed);
700
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);
711
714 result_type operator()();
715
718 void discard(unsigned long long n);
719
722 void reseed();
723
726 [[nodiscard]]
727 static constexpr result_type min() noexcept { return 0; }
728
731 [[nodiscard]]
732 static constexpr result_type max() noexcept { return UINT64_MAX; }
733
734 // 不提供:serialize/deserialize, operator<</>>, jump/longJump(CSPRNG 安全约束)
735
736 private:
737
738 std::array<std::uint32_t, 12> m_state; // key(8) + counter(1) + nonce(3),常数省略(generateBlock 时补齐)
739 std::array<std::uint8_t, 64> m_buffer; // 当前 block 的字节缓存
740 std::size_t m_bufferPos; // 缓存消费位置 [0, 64),==64 时触发新 block
741 std::uint64_t m_bytesSinceReseed; // 自上次 reseed 以来输出的字节数
742
743 void generateBlock(); // 跑一次 ChaCha20 block 函数填充 m_buffer
744 void reseedIfNecessary(); // m_bytesSinceReseed >= 阈值时自动 reseed
745 };
746}
747
749
750namespace RandX
751{
752 template <std::same_as<std::uint32_t> Uint32>
753 inline constexpr float FloatFromBits(const Uint32 i) noexcept
754 {
755 return (i >> 8) * 0x1.0p-24f;
756 }
757
758 template <std::same_as<std::uint64_t> Uint64>
759 inline constexpr double DoubleFromBits(const Uint64 i) noexcept
760 {
761 return (i >> 11) * 0x1.0p-53;
762 }
763
764 namespace detail
765 {
766 [[nodiscard]]
767 static constexpr std::uint64_t RotL(const std::uint64_t x, const int s) noexcept
768 {
769 return std::rotl(x, s);
770 }
771
772 [[nodiscard]]
773 static constexpr std::uint32_t RotL(const std::uint32_t x, const int s) noexcept
774 {
775 return std::rotl(x, s);
776 }
777
778 // 安全擦除内存(volatile 防止编译器死存储消除)
779 static void SecureWipe(void* ptr, std::size_t len) noexcept
780 {
781 volatile auto* p = static_cast<volatile std::uint8_t*>(ptr);
782 while (len--) *p++ = 0;
783 }
784
785 // 检测状态数组是否全零(全零是 xoshiro/xoroshiro 的吸收态)
786 template <std::size_t N>
787 [[nodiscard]]
788 static constexpr bool IsAllZero(const std::array<std::uint64_t, N>& state) noexcept
789 {
790 for (const auto& s : state) { if (s != 0) return false; }
791 return true;
792 }
793
794 template <std::size_t N>
795 [[nodiscard]]
796 static constexpr bool IsAllZero(const std::array<std::uint32_t, N>& state) noexcept
797 {
798 for (const auto& s : state) { if (s != 0) return false; }
799 return true;
800 }
801
802 // 尝试使用 RDRAND 获取 64 位硬件随机数
803 [[nodiscard]]
804 inline bool HardwareRand64(std::uint64_t& out) noexcept
805 {
806#if defined(__x86_64__) || defined(_M_X64)
807 #if defined(__RDRND__)
808 unsigned long long result;
809 if (__builtin_ia32_rdrand64_step(&result))
810 {
811 out = result;
812 return true;
813 }
814 #elif defined(_MSC_VER)
815 unsigned long long result;
816 if (_rdrand64_step(&result))
817 {
818 out = result;
819 return true;
820 }
821 #endif
822#endif
823 (void)out;
824 return false;
825 }
826
827 // ── A3 跨平台 OS 密码学熵源 ──
828 // 用 OS 密码学 API 填充 [buf, buf+n) 字节;成功返回 true。
829 // 平台优先级:Windows BCryptGenRandom → Linux getrandom → macOS SecRandomCopyBytes → std::random_device 兜底
830 // 注:getrandom 可能短读,内部循环直至填满;BCryptGenRandom/SecRandomCopyBytes 一次填满
831 [[nodiscard]]
832 inline bool GetOsEntropyBytes(void* buf, std::size_t n) noexcept
833 {
834 if (n == 0) return true;
835 auto* p = static_cast<std::uint8_t*>(buf);
836
837# if defined(_WIN32) && __has_include(<bcrypt.h>)
838 // Windows: BCryptGenRandom(分块处理 >4GB 时的 ULONG 截断)
839 // NTSTATUS >= 0 即 NT_SUCCESS(不能 == 0,正向 informational code 也属成功)
840 std::size_t filled = 0;
841 while (filled < n)
842 {
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)
845 {
846 return false;
847 }
848 filled += chunkSize;
849 }
850 return true;
851
852# elif defined(__linux__) && __has_include(<sys/random.h>)
853 // Linux: getrandom(循环处理短读与 EINTR)
854 std::size_t filled = 0;
855 while (filled < n)
856 {
857 const ssize_t ret = ::getrandom(p + filled, n - filled, 0);
858 if (ret < 0)
859 {
860 if (errno == EINTR) continue; // 被信号打断,重试
861 return false; // ENOSYS/EFAULT 等不可恢复错误
862 }
863 if (ret == 0) return false;
864 filled += static_cast<std::size_t>(ret);
865 }
866 return true;
867
868# elif defined(__APPLE__) && __has_include(<Security/Security.h>)
869 // macOS: SecRandomCopyBytes(一次调用填满)
870 return (::SecRandomCopyBytes(kSecRandomDefault, n, p) == errSecSuccess);
871
872# else
873 // 无可用 OS 密码学熵源 → 返回 false,SecureRandomBytes 将抛出异常
874 // 非安全场景的播种请使用 RandomSeed()(含 random_device → 时间戳回退链)
875 (void)p; (void)n;
876 return false;
877# endif
878 }
879
880 // 返回 true 当且仅当编译期检测到 OS 密码学熵源 API(BCryptGenRandom/getrandom/SecRandomCopyBytes)
881 // 返回 false 表示当前运行在 std::random_device 兜底路径,ChaCha20() 默认构造不保证密码学安全
882 [[nodiscard]]
883 inline bool HasCryptoGradeOsEntropy() noexcept
884 {
885# if (defined(_WIN32) && __has_include(<bcrypt.h>)) || (defined(__linux__) && __has_include(<sys/random.h>)) || (defined(__APPLE__) && __has_include(<Security/Security.h>))
886 return true;
887# else
888 return false;
889# endif
890 }
891
892 // ── A4 ChaCha20 常数与辅助 ──
893 // ChaCha20 常数 "expand 32-byte k"(RFC 8439 §2.3)
894 inline constexpr std::uint32_t ChaCha20Constants[4] = {
895 0x61707865u, 0x3320646eu, 0x79622d32u, 0x6b206574u
896 };
897 // 参考 NIST SP 800-90A reseed_interval 概念(SP 800-90A 涵盖 Hash/HMAC/CTR_DRBG,不含 ChaCha20;
898 // 此处借用其"周期性强制 reseed 提供前向安全"思想,取保守阈值)
899 inline constexpr std::uint64_t ChaCha20ReseedThreshold = 1ULL << 20; // 1 MB
900
901 // ChaCha20 quarter-round(仅 add/xor/rotl,常时间友好)
902 static void ChaCha20QuarterRound(std::uint32_t& a, std::uint32_t& b,
903 std::uint32_t& c, std::uint32_t& d) noexcept
904 {
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);
909 }
910
911 template <class Engine>
912 [[nodiscard]]
913 inline std::uint64_t Generate64Bits(Engine& engine)
914 {
915 if constexpr (sizeof(typename Engine::result_type) >= 8)
916 {
917 return static_cast<std::uint64_t>(engine());
918 }
919 else
920 {
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;
924 }
925 }
926
927 // 字符类型 concept(char/wchar_t/char8_t/char16_t/char32_t)
928 // char8_t 仅在 C++20+ 编译器下为基本类型,用特性检测宏条件启用
929 template <class T>
930 concept Character =
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>
937#endif
938 ;
939
940 // 检测 state_type 是否为可索引容器(排除标量如 SplitMix64 的 uint64_t)
941 template <class S>
942 concept IndexableState = requires(const S& cs, S& s) {
943 { cs.size() } -> std::same_as<std::size_t>;
944 { s[std::size_t{}] } -> std::same_as<typename S::value_type&>;
945 };
946
947 // 可序列化引擎 concept(仅对 state_type 为容器类的引擎生效)
948 template <class E>
949 concept SerializableEngine = requires(const E& ce, E& e) {
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;
954 };
955
964 template <class E>
965 concept JumpableEngine = requires(E& e) {
966 { e.jump() } -> std::same_as<void>;
967 };
968
979 template <class E>
981
982 // 迭代器可填充约束(RandFill 用)
983 template <class It, class T>
984 concept RandFillable = std::output_iterator<It, T>
985 && (std::integral<T> || std::floating_point<T>);
986
987 }
988
989 // ========================================================================
990 // 流式运算符 operator<< / operator>>
991 // 仅对 state_type 为可索引容器类的引擎生效(SerializableEngine concept)
992 // SplitMix64(state_type = uint64_t 标量)不支持,由 IndexableState 排除
993 // 格式兼容 std::random_engine:空格分隔的十进制数序列
994 // ========================================================================
995
996 // 流式输出引擎状态
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)
1000 {
1001 auto state = engine.serialize();
1002 for (std::size_t i = 0; i < state.size(); ++i)
1003 {
1004 if (i != 0) os << ' ';
1005 os << state[i];
1006 }
1007 return os;
1008 }
1009
1010 // 流式恢复引擎状态
1011 // 若解析失败(读取不足或流错误),setstate(failbit) 且引擎状态保持不变
1012 // (与 std::random_engine 一致:先读取到临时 state,全部成功才 deserialize)
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)
1016 {
1017 typename Engine::state_type state{};
1018 std::size_t i = 0;
1019 for (; i < state.size() && is; ++i)
1020 is >> state[i];
1021
1022 if (i == state.size() && is)
1023 {
1024 engine.deserialize(state);
1025 }
1026 else
1027 {
1028 is.setstate(std::ios_base::failbit);
1029 }
1030 return is;
1031 }
1032
1034 //
1035 // SplitMix64
1036 //
1037 inline constexpr SplitMix64::SplitMix64(const state_type state) noexcept
1038 : m_state(state) {}
1039
1040 template <class SeedSeq>
1041 requires (!std::same_as<std::remove_cvref_t<SeedSeq>, SplitMix64>)
1042 inline constexpr SplitMix64::SplitMix64(SeedSeq& seq)
1043 {
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];
1047 }
1048
1050 {
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);
1055 }
1056
1057 template <std::size_t N>
1058 inline constexpr std::array<std::uint64_t, N> SplitMix64::generateSeedSequence() noexcept
1059 {
1060 std::array<std::uint64_t, N> seeds = {};
1061
1062 for (auto& seed : seeds)
1063 {
1064 seed = operator()();
1065 }
1066
1067 return seeds;
1068 }
1069
1070 inline constexpr SplitMix64::result_type SplitMix64::min() noexcept
1071 {
1072 return std::numeric_limits<result_type>::lowest();
1073 }
1074
1075 inline constexpr SplitMix64::result_type SplitMix64::max() noexcept
1076 {
1077 return std::numeric_limits<result_type>::max();
1078 }
1079
1080 inline constexpr SplitMix64::state_type SplitMix64::serialize() const noexcept
1081 {
1082 return m_state;
1083 }
1084
1085 inline constexpr void SplitMix64::deserialize(const state_type state) noexcept
1086 {
1087 m_state = state;
1088 }
1089
1090 inline constexpr void SplitMix64::discard(const unsigned long long n) noexcept
1091 {
1092 for (unsigned long long i = 0; i < n; ++i) { operator()(); }
1093 }
1094
1096 //
1097 // xoshiro256**
1098 //
1099 inline constexpr Xoshiro256StarStar::Xoshiro256StarStar(const std::uint64_t seed) noexcept
1100 : m_state(SplitMix64{ seed }.generateSeedSequence<4>())
1101 {
1102 if (detail::IsAllZero(m_state)) m_state[0] = 1;
1103 }
1104
1105 template <class SeedSeq>
1106 requires (!std::same_as<std::remove_cvref_t<SeedSeq>, Xoshiro256StarStar>)
1107 inline constexpr Xoshiro256StarStar::Xoshiro256StarStar(SeedSeq& seq)
1108 {
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];
1113 if (detail::IsAllZero(m_state)) m_state[0] = 1;
1114 }
1115
1116 inline constexpr Xoshiro256StarStar::Xoshiro256StarStar(const state_type state) noexcept
1117 : m_state(state)
1118 {
1119 assert(!detail::IsAllZero(state) && "全零状态是吸收态,禁止使用");
1120 }
1121
1123 {
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];
1130 m_state[2] ^= t;
1131 m_state[3] = detail::RotL(m_state[3], 45);
1132 return result;
1133 }
1134
1135 inline constexpr void Xoshiro256StarStar::jump() noexcept
1136 {
1137 constexpr std::uint64_t JUMP[] = { 0x180ec6d33cfd0aba, 0xd5a61266f0c9392c, 0xa9582618e03fc9aa, 0x39abdc4529b1661c };
1138
1139 std::uint64_t s0 = 0;
1140 std::uint64_t s1 = 0;
1141 std::uint64_t s2 = 0;
1142 std::uint64_t s3 = 0;
1143
1144 for (std::uint64_t j : JUMP)
1145 {
1146 for (int b = 0; b < 64; ++b)
1147 {
1148 if (j & UINT64_C(1) << b)
1149 {
1150 s0 ^= m_state[0];
1151 s1 ^= m_state[1];
1152 s2 ^= m_state[2];
1153 s3 ^= m_state[3];
1154 }
1155 operator()();
1156 }
1157 }
1158
1159 m_state[0] = s0;
1160 m_state[1] = s1;
1161 m_state[2] = s2;
1162 m_state[3] = s3;
1163 }
1164
1165 inline constexpr void Xoshiro256StarStar::longJump() noexcept
1166 {
1167 constexpr std::uint64_t LONG_JUMP[] = { 0x76e15d3efefdcbbf, 0xc5004e441c522fb3, 0x77710069854ee241, 0x39109bb02acbe635 };
1168
1169 std::uint64_t s0 = 0;
1170 std::uint64_t s1 = 0;
1171 std::uint64_t s2 = 0;
1172 std::uint64_t s3 = 0;
1173
1174 for (std::uint64_t j : LONG_JUMP)
1175 {
1176 for (int b = 0; b < 64; ++b)
1177 {
1178 if (j & UINT64_C(1) << b)
1179 {
1180 s0 ^= m_state[0];
1181 s1 ^= m_state[1];
1182 s2 ^= m_state[2];
1183 s3 ^= m_state[3];
1184 }
1185 operator()();
1186 }
1187 }
1188
1189 m_state[0] = s0;
1190 m_state[1] = s1;
1191 m_state[2] = s2;
1192 m_state[3] = s3;
1193 }
1194
1196 {
1197 return std::numeric_limits<result_type>::lowest();
1198 }
1199
1201 {
1202 return std::numeric_limits<result_type>::max();
1203 }
1204
1206 {
1207 return m_state;
1208 }
1209
1210 inline constexpr void Xoshiro256StarStar::deserialize(const state_type state) noexcept
1211 {
1212 assert(!detail::IsAllZero(state) && "全零状态是吸收态,禁止使用");
1213 m_state = state;
1214 }
1215
1216 inline constexpr void Xoshiro256StarStar::discard(const unsigned long long n) noexcept
1217 {
1218 for (unsigned long long i = 0; i < n; ++i) { operator()(); }
1219 }
1220
1222 //
1223 // xoroshiro128**
1224 //
1225 inline constexpr Xoroshiro128StarStar::Xoroshiro128StarStar(const std::uint64_t seed) noexcept
1226 : m_state(SplitMix64{ seed }.generateSeedSequence<2>())
1227 {
1228 if (detail::IsAllZero(m_state)) m_state[0] = 1;
1229 }
1230
1231 template <class SeedSeq>
1232 requires (!std::same_as<std::remove_cvref_t<SeedSeq>, Xoroshiro128StarStar>)
1233 inline constexpr Xoroshiro128StarStar::Xoroshiro128StarStar(SeedSeq& seq)
1234 {
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];
1239 if (detail::IsAllZero(m_state)) m_state[0] = 1;
1240 }
1241
1242 inline constexpr Xoroshiro128StarStar::Xoroshiro128StarStar(const state_type state) noexcept
1243 : m_state(state)
1244 {
1245 assert(!detail::IsAllZero(state) && "全零状态是吸收态,禁止使用");
1246 }
1247
1249 {
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;
1253 s1 ^= s0;
1254 m_state[0] = detail::RotL(s0, 24) ^ s1 ^ (s1 << 16);
1255 m_state[1] = detail::RotL(s1, 37);
1256 return result;
1257 }
1258
1259 inline constexpr void Xoroshiro128StarStar::jump() noexcept
1260 {
1261 constexpr std::uint64_t JUMP[] = { 0xdf900294d8f554a5, 0x170865df4b3201fc };
1262
1263 std::uint64_t s0 = 0;
1264 std::uint64_t s1 = 0;
1265
1266 for (std::uint64_t j : JUMP)
1267 {
1268 for (int b = 0; b < 64; ++b)
1269 {
1270 if (j & UINT64_C(1) << b)
1271 {
1272 s0 ^= m_state[0];
1273 s1 ^= m_state[1];
1274 }
1275 operator()();
1276 }
1277 }
1278
1279 m_state[0] = s0;
1280 m_state[1] = s1;
1281 }
1282
1283 inline constexpr void Xoroshiro128StarStar::longJump() noexcept
1284 {
1285 constexpr std::uint64_t LONG_JUMP[] = { 0xd2a98b26625eee7b, 0xdddf9b1090aa7ac1 };
1286
1287 std::uint64_t s0 = 0;
1288 std::uint64_t s1 = 0;
1289
1290 for (std::uint64_t j : LONG_JUMP)
1291 {
1292 for (int b = 0; b < 64; ++b)
1293 {
1294 if (j & UINT64_C(1) << b)
1295 {
1296 s0 ^= m_state[0];
1297 s1 ^= m_state[1];
1298 }
1299 operator()();
1300 }
1301 }
1302
1303 m_state[0] = s0;
1304 m_state[1] = s1;
1305 }
1306
1308 {
1309 return std::numeric_limits<result_type>::lowest();
1310 }
1311
1313 {
1314 return std::numeric_limits<result_type>::max();
1315 }
1316
1318 {
1319 return m_state;
1320 }
1321
1322 inline constexpr void Xoroshiro128StarStar::deserialize(const state_type state) noexcept
1323 {
1324 assert(!detail::IsAllZero(state) && "全零状态是吸收态,禁止使用");
1325 m_state = state;
1326 }
1327
1328 inline constexpr void Xoroshiro128StarStar::discard(const unsigned long long n) noexcept
1329 {
1330 for (unsigned long long i = 0; i < n; ++i) { operator()(); }
1331 }
1332
1334 //
1335 // xoshiro128**
1336 //
1337 inline constexpr Xoshiro128StarStar::Xoshiro128StarStar(const std::uint64_t seed) noexcept
1338 : m_state()
1339 {
1340 SplitMix64 splitmix{ seed };
1341
1342 for (auto& state : m_state)
1343 {
1344 state = static_cast<std::uint32_t>(splitmix());
1345 }
1346 if (detail::IsAllZero(m_state)) m_state[0] = 1;
1347 }
1348
1349 template <class SeedSeq>
1350 requires (!std::same_as<std::remove_cvref_t<SeedSeq>, Xoshiro128StarStar>)
1351 inline constexpr Xoshiro128StarStar::Xoshiro128StarStar(SeedSeq& seq)
1352 {
1353 std::array<std::uint32_t, 4> seeds;
1354 seq.generate(seeds.begin(), seeds.end());
1355 m_state = seeds;
1356 if (detail::IsAllZero(m_state)) m_state[0] = 1;
1357 }
1358
1359 inline constexpr Xoshiro128StarStar::Xoshiro128StarStar(const state_type state) noexcept
1360 : m_state(state)
1361 {
1362 assert(!detail::IsAllZero(state) && "全零状态是吸收态,禁止使用");
1363 }
1364
1366 {
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];
1373 m_state[2] ^= t;
1374 m_state[3] = detail::RotL(m_state[3], 11);
1375 return result;
1376 }
1377
1378 inline constexpr void Xoshiro128StarStar::jump() noexcept
1379 {
1380 constexpr std::uint32_t JUMP[] = { 0x8764000b, 0xf542d2d3, 0x6fa035c3, 0x77f2db5b };
1381
1382 std::uint32_t s0 = 0;
1383 std::uint32_t s1 = 0;
1384 std::uint32_t s2 = 0;
1385 std::uint32_t s3 = 0;
1386
1387 for (std::uint32_t j : JUMP)
1388 {
1389 for (int b = 0; b < 32; ++b)
1390 {
1391 if (j & UINT32_C(1) << b)
1392 {
1393 s0 ^= m_state[0];
1394 s1 ^= m_state[1];
1395 s2 ^= m_state[2];
1396 s3 ^= m_state[3];
1397 }
1398 operator()();
1399 }
1400 }
1401
1402 m_state[0] = s0;
1403 m_state[1] = s1;
1404 m_state[2] = s2;
1405 m_state[3] = s3;
1406 }
1407
1408 inline constexpr void Xoshiro128StarStar::longJump() noexcept
1409 {
1410 constexpr std::uint32_t LONG_JUMP[] = { 0xb523952e, 0x0b6f099f, 0xccf5a0ef, 0x1c580662 };
1411
1412 std::uint32_t s0 = 0;
1413 std::uint32_t s1 = 0;
1414 std::uint32_t s2 = 0;
1415 std::uint32_t s3 = 0;
1416
1417 for (std::uint32_t j : LONG_JUMP)
1418 {
1419 for (int b = 0; b < 32; ++b)
1420 {
1421 if (j & UINT32_C(1) << b)
1422 {
1423 s0 ^= m_state[0];
1424 s1 ^= m_state[1];
1425 s2 ^= m_state[2];
1426 s3 ^= m_state[3];
1427 }
1428 operator()();
1429 }
1430 }
1431
1432 m_state[0] = s0;
1433 m_state[1] = s1;
1434 m_state[2] = s2;
1435 m_state[3] = s3;
1436 }
1437
1439 {
1440 return std::numeric_limits<result_type>::lowest();
1441 }
1442
1444 {
1445 return std::numeric_limits<result_type>::max();
1446 }
1447
1449 {
1450 return m_state;
1451 }
1452
1453 inline constexpr void Xoshiro128StarStar::deserialize(const state_type state) noexcept
1454 {
1455 assert(!detail::IsAllZero(state) && "全零状态是吸收态,禁止使用");
1456 m_state = state;
1457 }
1458
1459 inline constexpr void Xoshiro128StarStar::discard(const unsigned long long n) noexcept
1460 {
1461 for (unsigned long long i = 0; i < n; ++i) { operator()(); }
1462 }
1463
1465 //
1466 // xoroshiro64**
1467 //
1468 inline constexpr Xoroshiro64StarStar::Xoroshiro64StarStar(const std::uint64_t seed) noexcept
1469 : m_state()
1470 {
1471 SplitMix64 splitmix{ seed };
1472
1473 for (auto& state : m_state)
1474 {
1475 state = static_cast<std::uint32_t>(splitmix());
1476 }
1477 if (detail::IsAllZero(m_state)) m_state[0] = 1;
1478 }
1479
1480 template <class SeedSeq>
1481 requires (!std::same_as<std::remove_cvref_t<SeedSeq>, Xoroshiro64StarStar>)
1482 inline constexpr Xoroshiro64StarStar::Xoroshiro64StarStar(SeedSeq& seq)
1483 {
1484 std::array<std::uint32_t, 2> seeds;
1485 seq.generate(seeds.begin(), seeds.end());
1486 m_state = seeds;
1487 if (detail::IsAllZero(m_state)) m_state[0] = 1;
1488 }
1489
1490 inline constexpr Xoroshiro64StarStar::Xoroshiro64StarStar(const state_type state) noexcept
1491 : m_state(state)
1492 {
1493 assert(!detail::IsAllZero(state) && "全零状态是吸收态,禁止使用");
1494 }
1495
1497 {
1498 const std::uint32_t s0 = m_state[0];
1499 std::uint32_t s1 = m_state[1];
1500
1501 const std::uint32_t result = detail::RotL(s0 * 0x9E3779BB, 5) * 5;
1502
1503 s1 ^= s0;
1504 m_state[0] = detail::RotL(s0, 26) ^ s1 ^ (s1 << 9);
1505 m_state[1] = detail::RotL(s1, 13);
1506
1507 return result;
1508 }
1509
1511 {
1512 return std::numeric_limits<result_type>::lowest();
1513 }
1514
1516 {
1517 return std::numeric_limits<result_type>::max();
1518 }
1519
1521 {
1522 return m_state;
1523 }
1524
1525 inline constexpr void Xoroshiro64StarStar::deserialize(const state_type state) noexcept
1526 {
1527 assert(!detail::IsAllZero(state) && "全零状态是吸收态,禁止使用");
1528 m_state = state;
1529 }
1530
1531 inline constexpr void Xoroshiro64StarStar::discard(const unsigned long long n) noexcept
1532 {
1533 for (unsigned long long i = 0; i < n; ++i) { operator()(); }
1534 }
1535
1536
1538 //
1539 // SFC64 (Small Fast Counter)
1540 //
1541 inline constexpr SFC64::SFC64(const std::uint64_t seed) noexcept
1542 : m_a(0), m_b(0), m_c(0), m_counter(1)
1543 {
1544 // 使用 SplitMix64 播种 + 12 轮预热
1545 SplitMix64 sm{ seed };
1546 m_a = sm();
1547 m_b = sm();
1548 m_c = sm();
1549 for (int i = 0; i < 12; ++i) { operator()(); }
1550 }
1551
1552 template <class SeedSeq>
1553 requires (!std::same_as<std::remove_cvref_t<SeedSeq>, SFC64>)
1554 inline constexpr SFC64::SFC64(SeedSeq& seq)
1555 : m_counter(1)
1556 {
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];
1562 // 全零状态会导致输出可预测,强制修正
1563 if ((m_a | m_b | m_c) == 0) m_a = 0x9E3779B97F4A7C15ULL;
1564 // 与种子构造函数一致:12 轮预热
1565 for (int i = 0; i < 12; ++i) { operator()(); }
1566 }
1567
1568 inline constexpr SFC64::SFC64(const state_type state) noexcept
1569 : m_a(state[0]), m_b(state[1]), m_c(state[2]), m_counter(state[3]) {}
1570
1571 inline constexpr SFC64::result_type SFC64::operator()() noexcept
1572 {
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);
1576 m_c = detail::RotL(m_c, 24) + tmp;
1577 return tmp;
1578 }
1579
1580 inline constexpr SFC64::result_type SFC64::min() noexcept
1581 {
1582 return std::numeric_limits<result_type>::lowest();
1583 }
1584
1585 inline constexpr SFC64::result_type SFC64::max() noexcept
1586 {
1587 return std::numeric_limits<result_type>::max();
1588 }
1589
1590 inline constexpr SFC64::state_type SFC64::serialize() const noexcept
1591 {
1592 return { m_a, m_b, m_c, m_counter };
1593 }
1594
1595 inline constexpr void SFC64::deserialize(const state_type state) noexcept
1596 {
1597 m_a = state[0];
1598 m_b = state[1];
1599 m_c = state[2];
1600 m_counter = state[3];
1601 }
1602
1603 inline constexpr void SFC64::discard(const unsigned long long n) noexcept
1604 {
1605 for (unsigned long long i = 0; i < n; ++i) { operator()(); }
1606 }
1607
1609 //
1610 // RomuDuoJr
1611 //
1612 inline constexpr RomuDuoJr::RomuDuoJr(const std::uint64_t seed) noexcept
1613 : m_x(0), m_y(0)
1614 {
1615 SplitMix64 sm{ seed };
1616 m_x = sm();
1617 m_y = sm();
1618 // 确保不全零
1619 if (m_x == 0 && m_y == 0) { m_x = 1; }
1620 }
1621
1622 template <class SeedSeq>
1623 requires (!std::same_as<std::remove_cvref_t<SeedSeq>, RomuDuoJr>)
1624 inline constexpr RomuDuoJr::RomuDuoJr(SeedSeq& seq)
1625 {
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;
1631 }
1632
1633 inline constexpr RomuDuoJr::RomuDuoJr(const state_type state) noexcept
1634 : m_x(state[0]), m_y(state[1])
1635 {
1636 assert(!(m_x == 0 && m_y == 0) && "全零状态是吸收态,禁止使用");
1637 }
1638
1640 {
1641 const std::uint64_t xp = m_x;
1642 m_x = 15241094284759029579ULL * m_y;
1643 m_y = detail::RotL(m_y - xp, 27);
1644 return xp;
1645 }
1646
1647 inline constexpr RomuDuoJr::result_type RomuDuoJr::min() noexcept
1648 {
1649 return std::numeric_limits<result_type>::lowest();
1650 }
1651
1652 inline constexpr RomuDuoJr::result_type RomuDuoJr::max() noexcept
1653 {
1654 return std::numeric_limits<result_type>::max();
1655 }
1656
1657 inline constexpr RomuDuoJr::state_type RomuDuoJr::serialize() const noexcept
1658 {
1659 return { m_x, m_y };
1660 }
1661
1662 inline constexpr void RomuDuoJr::deserialize(const state_type state) noexcept
1663 {
1664 assert(!(state[0] == 0 && state[1] == 0) && "全零状态是吸收态,禁止使用");
1665 m_x = state[0];
1666 m_y = state[1];
1667 }
1668
1669 inline constexpr void RomuDuoJr::discard(const unsigned long long n) noexcept
1670 {
1671 for (unsigned long long i = 0; i < n; ++i) { operator()(); }
1672 }
1673
1675 //
1676 // 便捷工具函数
1677 //
1678
1682 [[nodiscard]]
1683 inline std::uint64_t RandomSeed()
1684 {
1685 std::uint64_t hw;
1686 if (detail::HardwareRand64(hw))
1687 return hw;
1688 if (detail::GetOsEntropyBytes(&hw, sizeof(hw)))
1689 return hw;
1690 std::random_device rd;
1691 try
1692 {
1693 return (static_cast<std::uint64_t>(rd()) << 32) | rd();
1694 }
1695 catch (...)
1696 {
1697 // 最终兜底:时间戳(非密码学,仅保证 RandomSeed 永不抛异常)
1698 return static_cast<std::uint64_t>(std::chrono::system_clock::now().time_since_epoch().count());
1699 }
1700 }
1701
1702 // 默认线程局部引擎,使用 RandomSeed() 播种(含 RDRAND → OS API → random_device → 时间戳回退链)
1703 [[nodiscard]]
1705 {
1706 thread_local Xoshiro256StarStar engine{ RandomSeed() };
1707 return engine;
1708 }
1709
1711
1715
1720 inline void SecureRandomBytes(void* buf, std::size_t n)
1721 {
1722 if (n == 0) return;
1723 if (!detail::GetOsEntropyBytes(buf, n))
1724 throw std::runtime_error("SecureRandomBytes: OS entropy source failed");
1725 }
1726
1729 [[nodiscard]]
1730 inline std::uint64_t SecureSeed()
1731 {
1732 std::uint64_t seed;
1733 SecureRandomBytes(&seed, sizeof(seed));
1734 return seed;
1735 }
1736
1740 [[nodiscard]]
1741 inline bool IsOsCryptoEntropyAvailable() noexcept
1742 {
1744 }
1745
1747 //
1748 // ChaCha20 (RFC 8439) — CSPRNG 引擎实现
1749 //
1750 // 状态矩阵布局(16 × uint32,常数省略存于 m_state[0..11]):
1751 // 0 1 2 3 "expa" "nd 3" "2-by" "te k" ← 常数(generateBlock 时补齐)
1752 // 4 5 6 7 key[0] key[1] key[2] key[3] ← m_state[0..3]
1753 // 8 9 10 11 key[4] key[5] key[6] key[7] ← m_state[4..7]
1754 // 12 13 14 15 ctr nonce[0] nonce[1] nonce[2]← m_state[8..11]
1755 //
1756 // 生成流程:operator() → reseedIfNecessary → (缓存耗尽时)generateBlock → 取 8 字节
1757 //
1758
1759 inline ChaCha20::ChaCha20(ChaCha20&& other) noexcept
1760 : m_state(other.m_state),
1761 m_buffer(other.m_buffer),
1762 m_bufferPos(other.m_bufferPos),
1763 m_bytesSinceReseed(other.m_bytesSinceReseed)
1764 {
1765 detail::SecureWipe(other.m_state.data(), sizeof(other.m_state));
1766 detail::SecureWipe(other.m_buffer.data(), sizeof(other.m_buffer));
1767 other.m_bufferPos = 64;
1768 other.m_bytesSinceReseed = 0;
1769 }
1770
1771 inline ChaCha20& ChaCha20::operator=(ChaCha20&& other) noexcept
1772 {
1773 if (this != &other)
1774 {
1775 detail::SecureWipe(m_state.data(), sizeof(m_state));
1776 detail::SecureWipe(m_buffer.data(), sizeof(m_buffer));
1777
1778 m_state = other.m_state;
1779 m_buffer = other.m_buffer;
1780 m_bufferPos = other.m_bufferPos;
1781 m_bytesSinceReseed = other.m_bytesSinceReseed;
1782
1783 detail::SecureWipe(other.m_state.data(), sizeof(other.m_state));
1784 detail::SecureWipe(other.m_buffer.data(), sizeof(other.m_buffer));
1785 other.m_bufferPos = 64;
1786 other.m_bytesSinceReseed = 0;
1787 }
1788 return *this;
1789 }
1790
1791 inline ChaCha20::~ChaCha20() noexcept
1792 {
1793 detail::SecureWipe(m_state.data(), sizeof(m_state));
1794 detail::SecureWipe(m_buffer.data(), sizeof(m_buffer));
1795 }
1796
1797 // 构造方式 1:从 OS 熵自动播种(密码学安全,默认)
1799 : m_state{}, m_buffer{}, m_bufferPos(64), m_bytesSinceReseed(0)
1800 {
1801 reseed(); // 从 OS 熵获取 key + nonce,重置 counter
1802 }
1803
1804 // 构造方式 2:显式种子(仅测试/复现,非密码学安全)
1805 // 用 SplitMix64 将 64-bit 种子扩展为 32 字节 key + 12 字节 nonce
1806 inline ChaCha20::ChaCha20(const std::uint64_t seed)
1807 : m_state{}, m_buffer{}, m_bufferPos(64), m_bytesSinceReseed(0)
1808 {
1809 SplitMix64 sm{ seed };
1810 // key: 前 4 次 SplitMix64 输出,每次 8 字节按小端序拆为 2 个 uint32
1811 for (int i = 0; i < 4; ++i)
1812 {
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);
1816 }
1817 // nonce: 第 5 次输出(8 字节)+ 第 6 次输出低 4 字节(丢弃高 4 字节)
1818 {
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);
1822 }
1823 m_state[11] = static_cast<std::uint32_t>(sm());
1824 m_state[8] = 0; // counter 初值 = 0
1825 }
1826
1827 // 构造方式 3:直接指定 key + nonce + counter
1828 inline ChaCha20::ChaCha20(const std::uint8_t* key, std::size_t keyLen,
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)
1832 {
1833 if (keyLen != 32)
1834 throw std::invalid_argument("ChaCha20: key must be 32 bytes");
1835 if (nonceLen != 12)
1836 throw std::invalid_argument("ChaCha20: nonce must be 12 bytes");
1837 // key → m_state[0..7](小端序)
1838 for (int i = 0; i < 8; ++i)
1839 {
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);
1844 }
1845 // nonce → m_state[9..11](小端序)
1846 for (int i = 0; i < 3; ++i)
1847 {
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);
1852 }
1853 m_state[8] = counter; // counter
1854 }
1855
1856 // 生成一个 ChaCha20 block(64 字节)填充 m_buffer
1857 inline void ChaCha20::generateBlock()
1858 {
1859 // 构造完整 16-word 状态:常数 + key + counter + nonce
1860 std::array<std::uint32_t, 16> state{};
1861 state[0] = detail::ChaCha20Constants[0];
1862 state[1] = detail::ChaCha20Constants[1];
1863 state[2] = detail::ChaCha20Constants[2];
1864 state[3] = detail::ChaCha20Constants[3];
1865 for (int i = 0; i < 8; ++i) state[4 + i] = m_state[i]; // key
1866 state[12] = m_state[8]; // counter
1867 state[13] = m_state[9]; // nonce[0]
1868 state[14] = m_state[10]; // nonce[1]
1869 state[15] = m_state[11]; // nonce[2]
1870
1871 std::array<std::uint32_t, 16> working = state;
1872
1873 // 20 轮 = 10 次 double-round(列轮 + 对角轮)
1874 for (int i = 0; i < 10; ++i)
1875 {
1876 // 列轮 QR 顺序:(0,4,8,12) (1,5,9,13) (2,6,10,14) (3,7,11,15)
1877 detail::ChaCha20QuarterRound(working[0], working[4], working[8], working[12]);
1878 detail::ChaCha20QuarterRound(working[1], working[5], working[9], working[13]);
1879 detail::ChaCha20QuarterRound(working[2], working[6], working[10], working[14]);
1880 detail::ChaCha20QuarterRound(working[3], working[7], working[11], working[15]);
1881 // 对角轮 QR 顺序:(0,5,10,15) (1,6,11,12) (2,7,8,13) (3,4,9,14)
1882 detail::ChaCha20QuarterRound(working[0], working[5], working[10], working[15]);
1883 detail::ChaCha20QuarterRound(working[1], working[6], working[11], working[12]);
1884 detail::ChaCha20QuarterRound(working[2], working[7], working[8], working[13]);
1885 detail::ChaCha20QuarterRound(working[3], working[4], working[9], working[14]);
1886 }
1887
1888 // 加初始状态后按小端序输出 64 字节到 m_buffer
1889 for (int i = 0; i < 16; ++i)
1890 {
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);
1896 }
1897
1898 if (m_state[8] == 0xFFFFFFFFU)
1899 {
1900 throw std::overflow_error("ChaCha20: 32-bit block counter overflow");
1901 }
1902 ++m_state[8]; // 递增 counter(2^20 字节阈值远早于 2^32 回绕,自动 reseed 防止复用)
1903 m_bufferPos = 0;
1904 }
1905
1906 // 自上次 reseed 以来输出字节数达到阈值时自动 reseed(前向安全)
1907 inline void ChaCha20::reseedIfNecessary()
1908 {
1909 if (m_bytesSinceReseed >= detail::ChaCha20ReseedThreshold)
1910 reseed();
1911 }
1912
1913 // 从 OS 熵重新播种:32 字节新 key + 12 字节新 nonce,重置 counter=0、缓存标记耗尽
1914 inline void ChaCha20::reseed()
1915 {
1916 std::array<std::uint8_t, 44> seed; // 32(key) + 12(nonce)
1917 SecureRandomBytes(seed.data(), seed.size());
1918 // key → m_state[0..7](小端序)
1919 for (int i = 0; i < 8; ++i)
1920 {
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);
1925 }
1926 // nonce → m_state[9..11](小端序)
1927 for (int i = 0; i < 3; ++i)
1928 {
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);
1933 }
1934 m_state[8] = 0; // counter 重置
1935 m_bufferPos = 64; // 强制下次 operator() 触发新 block
1936 m_bytesSinceReseed = 0;
1937 detail::SecureWipe(seed.data(), seed.size()); // 擦除栈上密钥材料
1938 detail::SecureWipe(m_buffer.data(), m_buffer.size()); // 擦除旧 keystream
1939 }
1940
1941 // 生成一个 64-bit 随机数(从缓存取 8 字节,缓存耗尽时生成新 block)
1943 {
1944 reseedIfNecessary();
1945 if (m_bufferPos == 64)
1946 generateBlock();
1947 // 从缓存取 8 字节,小端序组装为 uint64_t
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);
1951 m_bufferPos += 8;
1952 m_bytesSinceReseed += 8;
1953 return result;
1954 }
1955
1956 inline void ChaCha20::discard(const unsigned long long n)
1957 {
1958 for (unsigned long long i = 0; i < n; ++i) operator()();
1959 }
1960
1963 inline void Reseed(std::uint64_t seed)
1964 {
1966 }
1967
1969 inline void ReseedRandom()
1970 {
1972 }
1973
1975
1979
1984 template <std::integral T = int>
1985 [[nodiscard]]
1986 inline T RandInt(T min, T max)
1987 {
1988 assert(min <= max);
1989 std::uniform_int_distribution<T> dist(min, max);
1990 return dist(DefaultEngine());
1991 }
1992
1996 template <std::integral T = int>
1997 [[nodiscard]]
1998 inline T RandInt(T max)
1999 {
2000 assert(max >= T{0});
2001 return RandInt<T>(T{0}, max);
2002 }
2003
2008 template <std::floating_point T = double>
2009 [[nodiscard]]
2010 inline T RandReal(T min = T{0}, T max = T{1})
2011 {
2012 assert(std::isfinite(min) && std::isfinite(max) && min <= max);
2013 std::uniform_real_distribution<T> dist(min, max);
2014 return dist(DefaultEngine());
2015 }
2016
2020 [[nodiscard]]
2021 inline bool RandBool(double p = 0.5)
2022 {
2023 assert(std::isfinite(p) && p >= 0.0 && p <= 1.0);
2024 std::bernoulli_distribution dist(p);
2025 return dist(DefaultEngine());
2026 }
2027
2032 template <class Engine>
2033 [[nodiscard]]
2034 inline bool RandBool(Engine& engine, double p = 0.5)
2035 {
2036 assert(std::isfinite(p) && p >= 0.0 && p <= 1.0);
2037 std::bernoulli_distribution dist(p);
2038 return dist(engine);
2039 }
2040
2044 [[nodiscard]]
2045 inline bool RandBernoulli(double p = 0.5)
2046 {
2047 assert(p >= 0.0 && p <= 1.0);
2048 return RandBool(p);
2049 }
2050
2055 template <class Engine>
2056 [[nodiscard]]
2057 inline bool RandBernoulli(Engine& engine, double p = 0.5)
2058 {
2059 assert(p >= 0.0 && p <= 1.0);
2060 return RandBool(engine, p);
2061 }
2062
2068 template <detail::Character CharT>
2069 [[nodiscard]]
2070 inline CharT RandChar(CharT min, CharT max)
2071 {
2072 assert(min <= max);
2073 std::uniform_int_distribution<std::int64_t> dist(
2074 static_cast<std::int64_t>(min),
2075 static_cast<std::int64_t>(max));
2076 return static_cast<CharT>(dist(DefaultEngine()));
2077 }
2078
2082 template <detail::Character CharT = char>
2083 [[nodiscard]]
2084 inline CharT RandChar(CharT max)
2085 {
2086 return RandChar<CharT>(CharT{}, max);
2087 }
2088
2094 template <detail::Character CharT, class Engine>
2095 [[nodiscard]]
2096 inline CharT RandChar(Engine& engine, CharT min, CharT max)
2097 {
2098 assert(min <= 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));
2103 }
2104
2109 template <detail::Character CharT = char, class Engine>
2110 [[nodiscard]]
2111 inline CharT RandChar(Engine& engine, CharT max)
2112 {
2113 return RandChar<CharT>(engine, CharT{}, max);
2114 }
2115
2117
2121
2126 template <class Container>
2127 requires std::ranges::random_access_range<Container>
2128 [[nodiscard]]
2129 inline decltype(auto) RandElement(Container& c)
2130 {
2131 if (std::empty(c))
2132 throw std::invalid_argument("RandElement: empty container");
2133 return c[RandInt<std::size_t>(static_cast<std::size_t>(std::size(c) - 1))];
2134 }
2135
2140 template <class Container>
2141 requires std::ranges::random_access_range<Container>
2142 [[nodiscard]]
2143 inline std::ranges::range_value_t<Container> RandElement(Container&& c)
2144 {
2145 if (std::empty(c))
2146 throw std::invalid_argument("RandElement: empty container");
2147 return c[RandInt<std::size_t>(static_cast<std::size_t>(std::size(c) - 1))];
2148 }
2149
2155 template <std::random_access_iterator It>
2156 [[nodiscard]]
2157 inline It RandElement(It first, It last)
2158 {
2159 using Diff = std::iter_difference_t<It>;
2160 const Diff n = std::distance(first, last);
2161 if (n <= 0)
2162 throw std::invalid_argument("RandElement: empty range");
2163 return std::next(first, RandInt<Diff>(Diff{0}, n - 1));
2164 }
2165
2171 template <std::input_iterator It>
2172 requires (!std::random_access_iterator<It>)
2173 [[nodiscard]]
2174 inline It RandElement(It first, It last)
2175 {
2176 if (first == last)
2177 throw std::invalid_argument("RandElement: empty range");
2178 It selected = first;
2179 ++first;
2180 for (std::iter_difference_t<It> i = 1; first != last; ++first, ++i)
2181 {
2182 if (RandInt<std::iter_difference_t<It>>(0, i) == 0)
2183 selected = first;
2184 }
2185 return selected;
2186 }
2187
2193 template <std::random_access_iterator It, class Engine>
2194 [[nodiscard]]
2195 inline It RandElement(Engine& engine, It first, It last)
2196 {
2197 using Diff = std::iter_difference_t<It>;
2198 const Diff n = std::distance(first, last);
2199 if (n <= 0)
2200 throw std::invalid_argument("RandElement: empty range");
2201 return std::next(first, RandInt<Diff>(engine, Diff{0}, n - 1));
2202 }
2203
2209 template <std::input_iterator It, class Engine>
2210 requires (!std::random_access_iterator<It>)
2211 [[nodiscard]]
2212 inline It RandElement(Engine& engine, It first, It last)
2213 {
2214 if (first == last)
2215 throw std::invalid_argument("RandElement: empty range");
2216 It selected = first;
2217 ++first;
2218 for (std::iter_difference_t<It> i = 1; first != last; ++first, ++i)
2219 {
2220 if (RandInt<std::iter_difference_t<It>>(engine, std::iter_difference_t<It>{0}, i) == 0)
2221 selected = first;
2222 }
2223 return selected;
2224 }
2225
2226
2228
2232
2237 template <std::floating_point T = double>
2238 [[nodiscard]]
2239 inline T RandNormal(T mean = T{0}, T stddev = T{1})
2240 {
2241 assert(std::isfinite(mean) && std::isfinite(stddev) && stddev > T{0});
2242 std::normal_distribution<T> dist(mean, stddev);
2243 return dist(DefaultEngine());
2244 }
2245
2251 template <class Engine, std::floating_point T = double>
2252 [[nodiscard]]
2253 inline T RandNormal(Engine& engine, T mean = T{0}, T stddev = T{1})
2254 {
2255 assert(std::isfinite(mean) && std::isfinite(stddev) && stddev > T{0});
2256 std::normal_distribution<T> dist(mean, stddev);
2257 return dist(engine);
2258 }
2259
2262 template <std::ranges::random_access_range Container>
2263 inline void RandShuffle(Container&& c)
2264 {
2265 std::shuffle(c.begin(), c.end(), DefaultEngine());
2266 }
2267
2275 template <class It, class T>
2276 requires detail::RandFillable<It, T> && std::integral<T>
2277 inline void RandFill(It first, It last, T min, T max)
2278 {
2279 assert(min <= max);
2280 std::uniform_int_distribution<T> dist(min, max);
2281 for (; first != last; ++first)
2282 *first = dist(DefaultEngine());
2283 }
2284
2290 template <class It, std::floating_point T>
2291 requires std::output_iterator<It, T>
2292 inline void RandFill(It first, It last, T min, T max)
2293 {
2294 assert(min <= max);
2295 std::uniform_real_distribution<T> dist(min, max);
2296 for (; first != last; ++first)
2297 *first = dist(DefaultEngine());
2298 }
2299
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)
2309 {
2310 assert(min <= max);
2311 std::uniform_int_distribution<T> dist(min, max);
2312 for (; first != last; ++first)
2313 *first = dist(engine);
2314 }
2315
2322 template <class It, std::floating_point T, class Engine>
2323 requires std::output_iterator<It, T>
2324 inline void RandFill(Engine& engine, It first, It last, T min, T max)
2325 {
2326 assert(min <= max);
2327 std::uniform_real_distribution<T> dist(min, max);
2328 for (; first != last; ++first)
2329 *first = dist(engine);
2330 }
2331
2337 template <std::integral T = int>
2338 [[nodiscard]]
2339 inline std::vector<T> RandVector(T min, T max, std::size_t n)
2340 {
2341 assert(min <= max);
2342 std::vector<T> v;
2343 v.reserve(n);
2344 std::uniform_int_distribution<T> dist(min, max);
2345 auto& engine = DefaultEngine();
2346 for (std::size_t i = 0; i < n; ++i)
2347 v.push_back(dist(engine));
2348 return v;
2349 }
2350
2356 template <std::floating_point T = double>
2357 [[nodiscard]]
2358 inline std::vector<T> RandVector(T min, T max, std::size_t n)
2359 {
2360 assert(min <= max);
2361 std::vector<T> v;
2362 v.reserve(n);
2363 std::uniform_real_distribution<T> dist(min, max);
2364 auto& engine = DefaultEngine();
2365 for (std::size_t i = 0; i < n; ++i)
2366 v.push_back(dist(engine));
2367 return v;
2368 }
2369
2376 template <std::integral T = int, class Engine>
2377 [[nodiscard]]
2378 inline std::vector<T> RandVector(Engine& engine, T min, T max, std::size_t n)
2379 {
2380 assert(min <= max);
2381 std::vector<T> v;
2382 v.reserve(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));
2386 return v;
2387 }
2388
2395 template <std::floating_point T = double, class Engine>
2396 [[nodiscard]]
2397 inline std::vector<T> RandVector(Engine& engine, T min, T max, std::size_t n)
2398 {
2399 assert(min <= max);
2400 std::vector<T> v;
2401 v.reserve(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));
2405 return v;
2406 }
2407
2411 template <class WeightContainer>
2412 [[nodiscard]]
2413 inline typename WeightContainer::size_type RandWeighted(const WeightContainer& weights)
2414 {
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());
2418 return dist(DefaultEngine());
2419 }
2420
2425 template <class Engine, class WeightContainer>
2426 [[nodiscard]]
2427 inline typename WeightContainer::size_type RandWeighted(Engine& engine, const WeightContainer& weights)
2428 {
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);
2433 }
2434
2438 template <class IntType>
2439 [[nodiscard]]
2440 inline IntType RandWeighted(std::discrete_distribution<IntType>& dist)
2441 {
2442 return dist(DefaultEngine());
2443 }
2444
2449 template <class Engine, class IntType>
2450 [[nodiscard]]
2451 inline IntType RandWeighted(Engine& engine, std::discrete_distribution<IntType>& dist)
2452 {
2453 return dist(engine);
2454 }
2455
2461 template <std::integral T, class Engine>
2462 [[nodiscard]]
2463 inline T RandInt(Engine& engine, T min, T max)
2464 {
2465 assert(min <= max);
2466 std::uniform_int_distribution<T> dist(min, max);
2467 return dist(engine);
2468 }
2469
2475 template <std::floating_point T, class Engine>
2476 [[nodiscard]]
2477 inline T RandReal(Engine& engine, T min = T{0}, T max = T{1})
2478 {
2479 assert(std::isfinite(min) && std::isfinite(max) && min <= max);
2480 std::uniform_real_distribution<T> dist(min, max);
2481 return dist(engine);
2482 }
2483
2484
2485
2486 namespace detail
2487 {
2488 // 前向声明(定义见下方"编译期随机"节)
2489 [[nodiscard]]
2490 inline constexpr std::uint64_t BoundedRand(Xoshiro256StarStar& rng, std::uint64_t range) noexcept;
2491
2492 // RandSample 分支选择阈值:n·K < size 时用 hash-set(实测交叉点 n≈N/127,K=64 留 2× 裕度)
2493 inline constexpr std::uint64_t HashSetThresholdK = 64;
2494 }
2495
2497 //
2498 // RandChar / RandString 预设字符集(v1.2 新增)
2499 //
2500 // 提供常用字符集枚举,避免手写 ASCII 范围或字符串。
2501 //
2502
2503 // 预设字符集枚举
2504 enum class CharSet
2505 {
2506 Alphanumeric, // [A-Za-z0-9] 62 个
2507 Alpha, // [A-Za-z] 52 个
2508 Lower, // [a-z] 26 个
2509 Upper, // [A-Z] 26 个
2510 Digit, // [0-9] 10 个
2511 Hex, // [0-9a-f] 16 个
2512 Printable, // [!-~] 94 个可打印 ASCII
2513 Base64, // [A-Za-z0-9+/] 64 个(RFC 4648 §4 标准变体)
2514 Base64UrlSafe, // [A-Za-z0-9-_] 64 个(RFC 4648 §5 URL-safe 变体)
2515 };
2516
2517 namespace detail
2518 {
2519 // 返回预设字符集的字符串视图(零拷贝,指向静态存储)
2520 [[nodiscard]]
2521 inline std::string_view CharSetString(CharSet cs) noexcept
2522 {
2523 switch (cs)
2524 {
2526 return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
2527 case CharSet::Alpha:
2528 return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
2529 case CharSet::Lower:
2530 return "abcdefghijklmnopqrstuvwxyz";
2531 case CharSet::Upper:
2532 return "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
2533 case CharSet::Digit:
2534 return "0123456789";
2535 case CharSet::Hex:
2536 return "0123456789abcdef";
2537 case CharSet::Printable:
2538 return "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
2539 case CharSet::Base64:
2540 return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2542 return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
2543 }
2544 return "";
2545 }
2546 }
2547
2552 [[nodiscard]]
2553 inline char RandChar(CharSet cs)
2554 {
2555 const auto charset = detail::CharSetString(cs);
2556 if (charset.empty())
2557 throw std::invalid_argument("RandChar: charset is empty");
2558 auto& rng = DefaultEngine();
2559 std::uniform_int_distribution<std::size_t> dist(0, charset.size() - 1);
2560 return charset[dist(rng)];
2561 }
2562
2567 template <class Engine>
2568 [[nodiscard]]
2569 inline char RandChar(Engine& engine, CharSet cs)
2570 {
2571 const auto charset = detail::CharSetString(cs);
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)];
2576 }
2577
2579 //
2580 // 扩展便捷 API
2581 //
2582
2587 template <std::ranges::random_access_range Container>
2588 [[nodiscard]]
2589 inline auto RandSample(const Container& c, typename Container::size_type n)
2590 {
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;
2596 auto& rng = DefaultEngine();
2597 for (Size i = 0; i < n; ++i)
2598 {
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);
2604 }
2605 pool.resize(n);
2606 return pool;
2607 }
2608
2609 // ============================================================
2610 // RandSample 迭代器版(v1.2 新增)
2611 // 路径 1:随机访问迭代器 —— hash-set / 索引数组双分支
2612 // 路径 2:输入迭代器 —— reservoir sampling (Algorithm R, i+1 修复)
2613 // ============================================================
2614
2620 // 路径 1:随机访问迭代器(hash-set / 索引数组双分支)
2621 template <std::random_access_iterator It>
2622 [[nodiscard]]
2623 inline std::vector<std::iter_value_t<It>>
2624 RandSample(It first, It last, std::iter_difference_t<It> n)
2625 {
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)
2630 return {};
2631 if (n >= size)
2632 return std::vector<T>(first, last);
2633
2634 auto& rng = DefaultEngine();
2635
2636 // 分支选择:n·K < size 时 hash-set 内存优(O(n));否则索引数组常数优(O(N))
2637 // 用 uint64_t 避免 n*K 溢出(n 是 iter_difference_t,可能 32 位)
2638 const auto sizeU = static_cast<std::uint64_t>(size);
2639 // 线性阈值:n·K < size 时用 hash-set(实测交叉点 n≈N/127,K=64 留 2× 裕度)
2640 if (static_cast<std::uint64_t>(n) * detail::HashSetThresholdK < sizeU)
2641 {
2642 // hash-set 分支:O(n) 内存,O(n) 期望时间
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))
2648 {
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]);
2653 }
2654 return result;
2655 }
2656
2657 // 索引数组分支:O(N) 内存,O(N) 时间,无碰撞
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;
2661
2662 // Fisher-Yates 前 n 步:j ∈ [i, size-1]
2663 for (Diff i = 0; i < n; ++i)
2664 {
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)]);
2669 }
2670
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)]]);
2675 return result;
2676 }
2677
2683 // 路径 2:输入迭代器(reservoir sampling, Algorithm R, i+1 修复)
2684 template <std::input_iterator It>
2685 requires (!std::random_access_iterator<It>)
2686 [[nodiscard]]
2687 inline std::vector<std::iter_value_t<It>>
2688 RandSample(It first, It last, std::iter_difference_t<It> n)
2689 {
2690 using Diff = std::iter_difference_t<It>;
2691 using T = std::iter_value_t<It>;
2692 if (n <= 0)
2693 return {};
2694
2695 std::vector<T> reservoir;
2696 reservoir.reserve(static_cast<std::size_t>(n));
2697
2698 // 填满蓄水池
2699 Diff i = 0;
2700 for (; i < n && first != last; ++i, ++first)
2701 reservoir.push_back(*first);
2702
2703 if (first == last)
2704 return reservoir; // 元素不足 n,返回全部
2705
2706 // Algorithm R:第 i 个元素(i >= n,0-indexed)以 n/(i+1) 概率替换蓄水池随机位置
2707 // 关键:j ∈ [0, i](闭区间),uniform_int_distribution(0, i) 正好是 [0, i] 闭区间
2708 auto& rng = DefaultEngine();
2709 for (; first != last; ++i, ++first)
2710 {
2711 std::uniform_int_distribution<Diff> dist(Diff{0}, i);
2712 const Diff j = dist(rng);
2713 if (j < n)
2714 reservoir[static_cast<std::size_t>(j)] = *first;
2715 }
2716 return reservoir;
2717 }
2718
2725 // 引擎重载 —— 随机访问迭代器
2726 template <std::random_access_iterator It, class Engine>
2727 [[nodiscard]]
2728 inline std::vector<std::iter_value_t<It>>
2729 RandSample(Engine& engine, It first, It last, std::iter_difference_t<It> n)
2730 {
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)
2735 return {};
2736 if (n >= size)
2737 return std::vector<T>(first, last);
2738
2739 const auto sizeU = static_cast<std::uint64_t>(size);
2740 // 线性阈值:n·K < size 时用 hash-set(实测交叉点 n≈N/127,K=64 留 2× 裕度)
2741 if (static_cast<std::uint64_t>(n) * detail::HashSetThresholdK < sizeU)
2742 {
2743 // hash-set 分支:用 RandInt 适配任意引擎
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))
2749 {
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]);
2753 }
2754 return result;
2755 }
2756
2757 // 索引数组分支:Fisher-Yates 前 n 步,j ∈ [i, size-1]
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;
2761
2762 for (Diff i = 0; i < n; ++i)
2763 {
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)]);
2767 }
2768
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)]]);
2773 return result;
2774 }
2775
2782 // 引擎重载 —— 输入迭代器(reservoir)
2783 template <std::input_iterator It, class Engine>
2784 requires (!std::random_access_iterator<It>)
2785 [[nodiscard]]
2786 inline std::vector<std::iter_value_t<It>>
2787 RandSample(Engine& engine, It first, It last, std::iter_difference_t<It> n)
2788 {
2789 using Diff = std::iter_difference_t<It>;
2790 using T = std::iter_value_t<It>;
2791 if (n <= 0)
2792 return {};
2793
2794 std::vector<T> reservoir;
2795 reservoir.reserve(static_cast<std::size_t>(n));
2796
2797 Diff i = 0;
2798 for (; i < n && first != last; ++i, ++first)
2799 reservoir.push_back(*first);
2800
2801 if (first == last)
2802 return reservoir;
2803
2804 // Algorithm R:j ∈ [0, i] 闭区间,RandInt(a,b) 是闭区间故上界为 i
2805 for (; first != last; ++i, ++first)
2806 {
2807 const Diff j = RandInt<Diff>(engine, Diff{0}, i);
2808 if (j < n)
2809 reservoir[static_cast<std::size_t>(j)] = *first;
2810 }
2811 return reservoir;
2812 }
2813
2817 [[nodiscard]]
2818 inline std::vector<std::size_t> RandPermutation(std::size_t n)
2819 {
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;
2823 auto& rng = DefaultEngine();
2824 for (std::size_t i = n - 1; i > 0; --i)
2825 {
2826 std::uniform_int_distribution<std::size_t> dist(0, i);
2827 const std::size_t j = dist(rng);
2828 auto tmp = perm[i];
2829 perm[i] = perm[j];
2830 perm[j] = tmp;
2831 }
2832 return perm;
2833 }
2834
2836
2840
2846 [[nodiscard]]
2847 inline std::string RandString(std::size_t length, std::string_view charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
2848 {
2849 if (charset.empty())
2850 throw std::invalid_argument("RandString: charset is empty");
2851 std::string result(length, '\0');
2852 auto& rng = DefaultEngine();
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)];
2856 return result;
2857 }
2858
2863 [[nodiscard]]
2864 inline std::string RandString(std::size_t n, CharSet cs)
2865 {
2866 return RandString(n, detail::CharSetString(cs));
2867 }
2868
2874 template <class Engine>
2875 [[nodiscard]]
2876 inline std::string RandString(Engine& engine, std::size_t n, CharSet cs)
2877 {
2878 const auto charset = detail::CharSetString(cs);
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)];
2885 return result;
2886 }
2887
2891 template <std::floating_point T = double>
2892 [[nodiscard]]
2893 inline T RandExp(T lambda = T{1})
2894 {
2895 assert(std::isfinite(lambda) && lambda > T{0});
2896 std::exponential_distribution<T> dist(lambda);
2897 return dist(DefaultEngine());
2898 }
2899
2904 template <class Engine, std::floating_point T = double>
2905 [[nodiscard]]
2906 inline T RandExp(Engine& engine, T lambda = T{1})
2907 {
2908 assert(std::isfinite(lambda) && lambda > T{0});
2909 std::exponential_distribution<T> dist(lambda);
2910 return dist(engine);
2911 }
2912
2916 template <std::integral T = int>
2917 [[nodiscard]]
2918 inline T RandPoisson(double mean = 1.0)
2919 {
2920 assert(std::isfinite(mean) && mean >= 0.0);
2921 if (mean == 0.0) return T{0};
2922 std::poisson_distribution<T> dist(mean);
2923 return dist(DefaultEngine());
2924 }
2925
2930 template <class Engine, std::integral T = int>
2931 [[nodiscard]]
2932 inline T RandPoisson(Engine& engine, double mean = 1.0)
2933 {
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);
2938 }
2939
2944 template <std::floating_point T = double>
2945 [[nodiscard]]
2946 inline T RandGamma(T alpha = T{1}, T beta = T{1})
2947 {
2948 assert(std::isfinite(alpha) && std::isfinite(beta) && alpha > T{0} && beta > T{0});
2949 std::gamma_distribution<T> dist(alpha, beta);
2950 return dist(DefaultEngine());
2951 }
2952
2958 template <class Engine, std::floating_point T = double>
2959 [[nodiscard]]
2960 inline T RandGamma(Engine& engine, T alpha = T{1}, T beta = T{1})
2961 {
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);
2965 }
2966
2971 template <std::integral T = int>
2972 [[nodiscard]]
2973 inline T RandBinomial(T t = 1, double p = 0.5)
2974 {
2975 assert(t >= 0 && std::isfinite(p) && p >= 0.0 && p <= 1.0);
2976 std::binomial_distribution<T> dist(t, p);
2977 return dist(DefaultEngine());
2978 }
2979
2985 template <std::integral T = int, class Engine>
2986 [[nodiscard]]
2987 inline T RandBinomial(Engine& engine, T t = 1, double p = 0.5)
2988 {
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);
2992 }
2993
2998 template <std::floating_point T = double>
2999 [[nodiscard]]
3000 inline T RandLogNormal(T mean = T{0}, T stddev = T{1})
3001 {
3002 assert(std::isfinite(mean) && std::isfinite(stddev) && stddev > T{0});
3003 std::lognormal_distribution<T> dist(mean, stddev);
3004 return dist(DefaultEngine());
3005 }
3006
3012 template <std::floating_point T = double, class Engine>
3013 [[nodiscard]]
3014 inline T RandLogNormal(Engine& engine, T mean = T{0}, T stddev = T{1})
3015 {
3016 assert(std::isfinite(mean) && std::isfinite(stddev) && stddev > T{0});
3017 std::lognormal_distribution<T> dist(mean, stddev);
3018 return dist(engine);
3019 }
3020
3024 template <std::integral T = int>
3025 [[nodiscard]]
3026 inline T RandGeometric(double p = 0.5)
3027 {
3028 assert(p > 0.0 && p <= 1.0);
3029 std::geometric_distribution<T> dist(p);
3030 return dist(DefaultEngine());
3031 }
3032
3037 template <std::integral T = int, class Engine>
3038 [[nodiscard]]
3039 inline T RandGeometric(Engine& engine, double p = 0.5)
3040 {
3041 assert(p > 0.0 && p <= 1.0);
3042 std::geometric_distribution<T> dist(p);
3043 return dist(engine);
3044 }
3045
3050 template <std::floating_point T = double>
3051 [[nodiscard]]
3052 inline T RandCauchy(T a = T{0}, T b = T{1})
3053 {
3054 assert(std::isfinite(a) && std::isfinite(b) && b > T{0});
3055 std::cauchy_distribution<T> dist(a, b);
3056 return dist(DefaultEngine());
3057 }
3058
3064 template <std::floating_point T = double, class Engine>
3065 [[nodiscard]]
3066 inline T RandCauchy(Engine& engine, T a = T{0}, T b = T{1})
3067 {
3068 assert(std::isfinite(a) && std::isfinite(b) && b > T{0});
3069 std::cauchy_distribution<T> dist(a, b);
3070 return dist(engine);
3071 }
3072
3077 template <std::floating_point T = double>
3078 [[nodiscard]]
3079 inline T RandWeibull(T a = T{1}, T b = T{1})
3080 {
3081 assert(std::isfinite(a) && std::isfinite(b) && a > T{0} && b > T{0});
3082 std::weibull_distribution<T> dist(a, b);
3083 return dist(DefaultEngine());
3084 }
3085
3091 template <std::floating_point T = double, class Engine>
3092 [[nodiscard]]
3093 inline T RandWeibull(Engine& engine, T a = T{1}, T b = T{1})
3094 {
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);
3098 }
3099
3104 template <std::floating_point T = double>
3105 [[nodiscard]]
3106 inline T RandExtremeValue(T a = T{0}, T b = T{1})
3107 {
3108 assert(std::isfinite(a) && std::isfinite(b) && b > T{0});
3109 std::extreme_value_distribution<T> dist(a, b);
3110 return dist(DefaultEngine());
3111 }
3112
3118 template <std::floating_point T = double, class Engine>
3119 [[nodiscard]]
3120 inline T RandExtremeValue(Engine& engine, T a = T{0}, T b = T{1})
3121 {
3122 assert(std::isfinite(a) && std::isfinite(b) && b > T{0});
3123 std::extreme_value_distribution<T> dist(a, b);
3124 return dist(engine);
3125 }
3126
3130 template <std::floating_point T = double>
3131 [[nodiscard]]
3132 inline T RandChiSquared(T n = T{1})
3133 {
3134 assert(std::isfinite(n) && n > T{0});
3135 std::chi_squared_distribution<T> dist(n);
3136 return dist(DefaultEngine());
3137 }
3138
3143 template <std::floating_point T = double, class Engine>
3144 [[nodiscard]]
3145 inline T RandChiSquared(Engine& engine, T n = T{1})
3146 {
3147 assert(std::isfinite(n) && n > T{0});
3148 std::chi_squared_distribution<T> dist(n);
3149 return dist(engine);
3150 }
3151
3155 template <std::floating_point T = double>
3156 [[nodiscard]]
3157 inline T RandStudentT(T n = T{1})
3158 {
3159 assert(std::isfinite(n) && n > T{0});
3160 std::student_t_distribution<T> dist(n);
3161 return dist(DefaultEngine());
3162 }
3163
3168 template <std::floating_point T = double, class Engine>
3169 [[nodiscard]]
3170 inline T RandStudentT(Engine& engine, T n = T{1})
3171 {
3172 assert(std::isfinite(n) && n > T{0});
3173 std::student_t_distribution<T> dist(n);
3174 return dist(engine);
3175 }
3176
3181 template <std::floating_point T = double>
3182 [[nodiscard]]
3183 inline T RandFisherF(T m = T{1}, T n = T{1})
3184 {
3185 assert(std::isfinite(m) && std::isfinite(n) && m > T{0} && n > T{0});
3186 std::fisher_f_distribution<T> dist(m, n);
3187 return dist(DefaultEngine());
3188 }
3189
3195 template <std::floating_point T = double, class Engine>
3196 [[nodiscard]]
3197 inline T RandFisherF(Engine& engine, T m = T{1}, T n = T{1})
3198 {
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);
3202 }
3203
3209 template <std::floating_point T = double>
3210 [[nodiscard]]
3211 inline T RandBeta(T a = T{1}, T b = T{1})
3212 {
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});
3216 auto& rng = DefaultEngine();
3217 const T x = distA(rng);
3218 const T y = distB(rng);
3219 const T sum = x + y;
3220 if (sum == T{0})
3221 return RandBool(rng, static_cast<double>(a) / static_cast<double>(a + b)) ? T{1} : T{0};
3222 return x / sum;
3223 }
3224
3230 template <std::floating_point T = double, class Engine>
3231 [[nodiscard]]
3232 inline T RandBeta(Engine& engine, T a = T{1}, T b = T{1})
3233 {
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;
3240 if (sum == T{0})
3241 return RandBool(engine, static_cast<double>(a) / static_cast<double>(a + b)) ? T{1} : T{0};
3242 return x / sum;
3243 }
3244
3248 template <int N, std::integral T = std::uint64_t>
3249 requires (N > 0 && N <= 64 && N <= std::numeric_limits<T>::digits)
3250 [[nodiscard]]
3251 inline T RandBits() noexcept
3252 {
3253 auto& rng = DefaultEngine();
3254 if constexpr (N == 64)
3255 return static_cast<T>(rng());
3256 else
3257 return static_cast<T>(rng() & ((std::uint64_t{1} << N) - 1));
3258 }
3259
3264 template <class Engine>
3265 [[nodiscard]]
3266 inline std::string RandUUID(Engine& engine)
3267 {
3268 static constexpr char hex[] = "0123456789abcdef";
3269 std::string uuid(36, '-');
3270 const std::uint64_t u1 = detail::Generate64Bits(engine);
3271 const std::uint64_t u2 = detail::Generate64Bits(engine);
3272
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];
3277 uuid[14] = '4';
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];
3285
3286 return uuid;
3287 }
3288
3289 [[nodiscard]]
3290 inline std::string RandUUID()
3291 {
3292 return RandUUID(DefaultEngine());
3293 }
3294
3296 //
3297 // 多流接口(并行计算)
3298 //
3299
3305 template <class Engine>
3306 requires detail::StreamEngine<Engine>
3307 [[nodiscard]]
3308 inline constexpr Engine MakeStreamEngine(std::uint64_t streamId, std::uint64_t seed = DefaultSeed)
3309 {
3310 Engine rng{ seed };
3311 for (std::uint64_t i = 0; i < streamId; ++i)
3312 rng.jump();
3313 return rng;
3314 }
3315
3317 //
3318 // 编译期随机(constexpr)
3319 //
3320
3321 namespace detail
3322 {
3323#ifdef __SIZEOF_INT128__
3324 // Lemire 快速有界法:返回 [0, range) 内均匀分布的随机数,无模偏差
3325 // 使用 __uint128_t(GCC/Clang constexpr 友好)
3326 [[nodiscard]]
3327 inline constexpr std::uint64_t BoundedRand(Xoshiro256StarStar& rng, std::uint64_t range) noexcept
3328 {
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);
3332 if (low < range)
3333 {
3334 const std::uint64_t threshold = (0ULL - range) % range;
3335 while (low < threshold)
3336 {
3337 product = static_cast<__uint128_t>(rng()) * range;
3338 low = static_cast<std::uint64_t>(product);
3339 }
3340 }
3341 return static_cast<std::uint64_t>(product >> 64);
3342 }
3343#else
3344 // 拒绝采样回退(MSVC 无 __uint128_t)
3345 [[nodiscard]]
3346 inline constexpr std::uint64_t BoundedRand(Xoshiro256StarStar& rng, std::uint64_t range) noexcept
3347 {
3348 if (range == 0) return 0;
3349 const std::uint64_t threshold = (0ULL - range) % range;
3350 std::uint64_t r;
3351 do { r = rng(); } while (r < threshold);
3352 return r % range;
3353 }
3354#endif
3355 }
3356
3361 template <std::integral T = int, std::uint64_t Seed = DefaultSeed>
3362 [[nodiscard]]
3363 inline constexpr T RandIntCE(T min, T max)
3364 {
3365 if (min > max) throw std::invalid_argument("RandIntCE: min > max");
3366 Xoshiro256StarStar rng{ Seed };
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)())
3372 {
3373 return static_cast<T>(u_min + static_cast<U>(rng()));
3374 }
3375 const auto range = static_cast<std::uint64_t>(diff) + 1;
3376 return static_cast<T>(u_min + static_cast<U>(detail::BoundedRand(rng, range)));
3377 }
3378
3382 template <std::integral T = int, std::uint64_t Seed = DefaultSeed>
3383 [[nodiscard]]
3384 inline constexpr T RandIntCE(T max)
3385 {
3386 return RandIntCE<T, Seed>(T{0}, max);
3387 }
3388
3390 //
3391 // 编译期洗牌(constexpr)
3392 //
3393
3400 template <std::random_access_iterator It, std::uint64_t Seed = DefaultSeed>
3401 constexpr void ShuffleCE(It first, It last) noexcept
3402 {
3403 const auto n = static_cast<std::uint64_t>(last - first);
3404 if (n < 2) return;
3405 Xoshiro256StarStar rng{ Seed };
3406 for (std::uint64_t i = n - 1; i > 0; --i)
3407 {
3408 const auto j = detail::BoundedRand(rng, i + 1);
3409 if (i != j)
3410 {
3411 auto tmp = std::move(first[i]);
3412 first[i] = std::move(first[j]);
3413 first[j] = std::move(tmp);
3414 }
3415 }
3416 }
3417
3424 template <class T, std::size_t N, std::uint64_t Seed = DefaultSeed>
3425 [[nodiscard]]
3426 constexpr std::array<T, N> ShuffledArray(std::array<T, N> arr) noexcept
3427 {
3428 ShuffleCE<decltype(arr.begin()), Seed>(arr.begin(), arr.end());
3429 return arr;
3430 }
3431
3433
3435 //
3436 // 静态断言:确认引擎满足 uniform_random_bit_generator 概念
3437 //
3438
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>);
3447
3451
3452 namespace ranges
3453 {
3458 template <std::ranges::input_range R>
3459 requires std::ranges::sized_range<R> || std::ranges::forward_range<R>
3460 [[nodiscard]]
3461 inline std::ranges::range_value_t<R>
3463 {
3464 return *RandX::RandElement(std::ranges::begin(r), std::ranges::end(r));
3465 }
3466
3471 template <std::ranges::input_range R>
3472 [[nodiscard]]
3473 inline std::vector<std::ranges::range_value_t<R>>
3474 RandSample(R&& r, std::ranges::range_difference_t<R> n)
3475 {
3476 return RandX::RandSample(std::ranges::begin(r), std::ranges::end(r), n);
3477 }
3478
3481 template <std::ranges::random_access_range R>
3482 requires std::ranges::sized_range<R>
3483 inline void
3485 {
3486 std::ranges::shuffle(r, RandX::DefaultEngine());
3487 }
3488
3494 template <class T, std::ranges::output_range<const T&> R>
3495 inline void
3496 RandFill(R&& r, T min, T max)
3497 {
3498 RandX::RandFill(std::ranges::begin(r), std::ranges::end(r), min, max);
3499 }
3500 }
3501
3503
3504}
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
定义 RandX.hpp:930
定义 RandX.hpp:942
可跳跃引擎概念:支持 jump() 前进 2^N 步
定义 RandX.hpp:965
定义 RandX.hpp:984
流式引擎概念:可通过 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
CharSet
定义 RandX.hpp:2505
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
@ Upper
定义 RandX.hpp:2509
@ Base64
定义 RandX.hpp:2513
@ Base64UrlSafe
定义 RandX.hpp:2514
@ Printable
定义 RandX.hpp:2512
@ Alpha
定义 RandX.hpp:2507
@ Digit
定义 RandX.hpp:2510
@ Hex
定义 RandX.hpp:2511
@ Lower
定义 RandX.hpp:2508
@ 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
定义 RandX.hpp:765
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
定义 RandX.hpp:3453
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
定义 RandX.hpp:138
constexpr std::uint64_t DefaultSeed
定义 RandX.hpp:140