RandX 1.4.3
基于 xoshiro/xoroshiro 算法族的纯头文件伪随机数生成器库
载入中...
搜索中...
未找到
RandX_Cpp17.hpp
浏览该文件的文档.
1//----------------------------------------------------------------------------------------
2//
3// RandX_Cpp17.hpp — 基于 Xoshiro 的伪随机数生成器封装库(C++17 / 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_Cpp17.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// RandX::Xoshiro256StarStar rng{ RandX::RandomSeed() };
35// int val = RandX::RandInt(rng, 0, 99);
36//
37// // 配合标准库 distribution(满足 UniformRandomBitGenerator)
38// std::normal_distribution<double> norm(0.0, 1.0);
39// double sample = norm(rng);
40//
41// 多流并行
42//
43// auto s0 = RandX::MakeStreamEngine<RandX::Xoshiro256StarStar>(0);
44// auto s1 = RandX::MakeStreamEngine<RandX::Xoshiro256StarStar>(1);
45//
46// 序列化 / 反序列化
47//
48// auto state = rng.serialize();
49// rng.deserialize(state);
50//
51// 跳跃
52//
53// rng.jump(); // 前进 2^128 步(xoshiro256 系列)
54// rng.longJump(); // 前进 2^192 步
55// rng.discard(1000);
56//
57// 引擎选择指南
58//
59// 引擎 输出 周期 状态 适用场景
60// ─────────────────────────────────────────────────────────────
61// Xoshiro256StarStar 64-bit 2^256-1 32B 通用首选,统计质量最优
62// Xoroshiro128StarStar 64-bit 2^128-1 16B 内存受限,统计更优
63// Xoshiro128StarStar 32-bit 2^128-1 16B 32 位平台,统计更优
64// Xoroshiro64StarStar 32-bit 2^64-1 8B 极端内存受限
65// SplitMix64 64-bit 2^64 8B 种子扩展 / 哈希,非通用 PRNG
66// SFC64 64-bit >= 2^64 32B 速度极快,通过 PractRand
67// RomuDuoJr 64-bit >= 2^51 16B 极简极快,非关键模拟
68// ChaCha20 64-bit 无周期 48B+ 密码学安全 CSPRNG(RFC 8439)
69//
70// ⚠️ 安全声明
71// 本库的 xoshiro/xoroshiro/SFC64/RomuDuoJr 引擎均非 CSPRNG。
72// 状态可从输出逆推,不可用于密码/密钥/会话 token 等安全场景。
73// 此类场景请使用 ChaCha20 引擎或 SecureRandomBytes()。
74//
75//----------------------------------------------------------------------------------------
76
77# pragma once
78# include <cstdint>
79# include <array>
80# include <limits>
81# include <type_traits>
82# include <random>
83# include <algorithm>
84# include <cassert>
85# include <string>
86# include <string_view>
87# include <unordered_set>
88# include <vector>
89# include <stdexcept>
90# include <ios> // std::ios_base::failbit(operator>> 所需)
91# include <istream> // std::basic_istream(operator>> 所需完整类型)
92# include <ostream> // std::basic_ostream(operator<< 所需完整类型)
93# if defined(_MSC_VER) && (defined(__x86_64__) || defined(_M_X64))
94# include <immintrin.h>
95# endif
96// ── A3 跨平台 OS 熵源头文件(条件包含) ──
97# if defined(_WIN32) && __has_include(<bcrypt.h>)
98// bcrypt.h 依赖 <windows.h> 提供的 ULONG/NTSTATUS 等类型(MSVC 和 MinGW 均需)
99// NOMINMAX 阻止 <windows.h> 定义 min/max 宏(与引擎的 min()/max() 方法冲突)
100# ifndef WIN32_LEAN_AND_MEAN
101# define WIN32_LEAN_AND_MEAN
102# endif
103# ifndef NOMINMAX
104# define NOMINMAX
105# endif
106# include <windows.h>
107# include <bcrypt.h>
108# pragma comment(lib, "bcrypt.lib") // 仅 MSVC 生效
109// MinGW 不支持 #pragma comment(lib),须手动添加 -lbcrypt 链接选项
110# if(defined(__MINGW32__) || defined(__MINGW64__)) && !defined(RANDX_SUPPRESS_LINK_HINT)
111# pragma message("RandX: MinGW 需手动链接 bcrypt(编译命令添加 -lbcrypt)")
112# endif
113# elif defined(__linux__) && __has_include(<sys/random.h>)
114# include <sys/random.h>
115# include <cerrno>
116# elif defined(__APPLE__) && __has_include(<Security/Security.h>)
117# include <Security/Security.h>
118# endif
119# include <chrono> // std::chrono(RandomSeed 时间戳兜底用)
120# include <cstring> // std::memcpy(std::random_device 回退路径用)
121# if __has_cpp_attribute(nodiscard) >= 201907L
122# define RANDX_NODISCARD_CXX20 [[nodiscard]]
123# else
124# define RANDX_NODISCARD_CXX20
125# endif
126
127namespace RandX
128{
129 // 生成器的默认种子值
130 inline constexpr std::uint64_t DefaultSeed = 1234567890ULL;
131
132 // 将给定的 uint32 值 `i` 转换为 32 位浮点
133 // 范围在 [0.0f, 1.0f) 的数值
134 template <class Uint32, std::enable_if_t<std::is_same_v<Uint32, std::uint32_t>>* = nullptr>
135 [[nodiscard]]
136 inline constexpr float FloatFromBits(Uint32 i) noexcept;
137
138 // 将给定的 uint64 值 `i` 转换为 64 位浮点
139 // 范围在 [0.0, 1.0) 的数值
140 template <class Uint64, std::enable_if_t<std::is_same_v<Uint64, std::uint64_t>>* = nullptr>
141 [[nodiscard]]
142 inline constexpr double DoubleFromBits(Uint64 i) noexcept;
143
146
155 class SplitMix64
156 {
157 public:
158
159 using state_type = std::uint64_t;
160 using result_type = std::uint64_t;
161
165 explicit constexpr SplitMix64(state_type state = DefaultSeed) noexcept;
166
169 template <class SeedSeq,
170 std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>, SplitMix64>>* = nullptr>
172 explicit constexpr SplitMix64(SeedSeq& seq);
173
176 constexpr result_type operator()() noexcept;
177
180 constexpr void discard(unsigned long long n) noexcept;
181
185 template <std::size_t N>
186 [[nodiscard]]
187 constexpr std::array<std::uint64_t, N> generateSeedSequence() noexcept;
188
191 [[nodiscard]]
192 static constexpr result_type min() noexcept;
193
196 [[nodiscard]]
197 static constexpr result_type max() noexcept;
198
202 [[nodiscard]]
203 constexpr state_type serialize() const noexcept;
204
208 constexpr void deserialize(state_type state) noexcept;
209
210 [[nodiscard]]
211 friend bool operator ==(const SplitMix64& lhs, const SplitMix64& rhs) noexcept
212 {
213 return (lhs.m_state == rhs.m_state);
214 }
215
216 [[nodiscard]]
217 friend bool operator !=(const SplitMix64& lhs, const SplitMix64& rhs) noexcept
218 {
219 return (lhs.m_state != rhs.m_state);
220 }
221
222 private:
223
224 state_type m_state;
225 };
226
235 class Xoshiro256StarStar
236 {
237 public:
238
239 using state_type = std::array<std::uint64_t, 4>;
240 using result_type = std::uint64_t;
241
245 explicit constexpr Xoshiro256StarStar(std::uint64_t seed = DefaultSeed) noexcept;
246
249 template <class SeedSeq,
250 std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>, Xoshiro256StarStar>>* = nullptr>
252 explicit constexpr Xoshiro256StarStar(SeedSeq& seq);
253
257 explicit constexpr Xoshiro256StarStar(state_type state) noexcept;
258
261 constexpr result_type operator()() noexcept;
262
265 constexpr void discard(unsigned long long n) noexcept;
266
270 constexpr void jump() noexcept;
271
275 constexpr void longJump() noexcept;
276
279 [[nodiscard]]
280 static constexpr result_type min() noexcept;
281
284 [[nodiscard]]
285 static constexpr result_type max() noexcept;
286
290 [[nodiscard]]
291 constexpr state_type serialize() const noexcept;
292
296 constexpr void deserialize(state_type state) noexcept;
297
298 [[nodiscard]]
299 friend bool operator ==(const Xoshiro256StarStar& lhs, const Xoshiro256StarStar& rhs) noexcept
300 {
301 return (lhs.m_state == rhs.m_state);
302 }
303
304 [[nodiscard]]
305 friend bool operator !=(const Xoshiro256StarStar& lhs, const Xoshiro256StarStar& rhs) noexcept
306 {
307 return (lhs.m_state != rhs.m_state);
308 }
309
310 private:
311
312 state_type m_state;
313 };
314
323 class Xoroshiro128StarStar
324 {
325 public:
326
327 using state_type = std::array<std::uint64_t, 2>;
328 using result_type = std::uint64_t;
329
333 explicit constexpr Xoroshiro128StarStar(std::uint64_t seed = DefaultSeed) noexcept;
334
337 template <class SeedSeq,
338 std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>, Xoroshiro128StarStar>>* = nullptr>
340 explicit constexpr Xoroshiro128StarStar(SeedSeq& seq);
341
345 explicit constexpr Xoroshiro128StarStar(state_type state) noexcept;
346
349 constexpr result_type operator()() noexcept;
350
353 constexpr void discard(unsigned long long n) noexcept;
354
358 constexpr void jump() noexcept;
359
363 constexpr void longJump() noexcept;
364
367 [[nodiscard]]
368 static constexpr result_type min() noexcept;
369
372 [[nodiscard]]
373 static constexpr result_type max() noexcept;
374
378 [[nodiscard]]
379 constexpr state_type serialize() const noexcept;
380
384 constexpr void deserialize(state_type state) noexcept;
385
386 [[nodiscard]]
387 friend bool operator ==(const Xoroshiro128StarStar& lhs, const Xoroshiro128StarStar& rhs) noexcept
388 {
389 return (lhs.m_state == rhs.m_state);
390 }
391
392 [[nodiscard]]
393 friend bool operator !=(const Xoroshiro128StarStar& lhs, const Xoroshiro128StarStar& rhs) noexcept
394 {
395 return (lhs.m_state != rhs.m_state);
396 }
397
398 private:
399
400 state_type m_state;
401 };
402
411 class Xoshiro128StarStar
412 {
413 public:
414
415 using state_type = std::array<std::uint32_t, 4>;
416 using result_type = std::uint32_t;
417
421 explicit constexpr Xoshiro128StarStar(std::uint64_t seed = DefaultSeed) noexcept;
422
425 template <class SeedSeq,
426 std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>, Xoshiro128StarStar>>* = nullptr>
428 explicit constexpr Xoshiro128StarStar(SeedSeq& seq);
429
433 explicit constexpr Xoshiro128StarStar(state_type state) noexcept;
434
437 constexpr result_type operator()() noexcept;
438
441 constexpr void discard(unsigned long long n) noexcept;
442
446 constexpr void jump() noexcept;
447
451 constexpr void longJump() noexcept;
452
455 [[nodiscard]]
456 static constexpr result_type min() noexcept;
457
460 [[nodiscard]]
461 static constexpr result_type max() noexcept;
462
466 [[nodiscard]]
467 constexpr state_type serialize() const noexcept;
468
472 constexpr void deserialize(state_type state) noexcept;
473
474 [[nodiscard]]
475 friend bool operator ==(const Xoshiro128StarStar& lhs, const Xoshiro128StarStar& rhs) noexcept
476 {
477 return (lhs.m_state == rhs.m_state);
478 }
479
480 [[nodiscard]]
481 friend bool operator !=(const Xoshiro128StarStar& lhs, const Xoshiro128StarStar& rhs) noexcept
482 {
483 return (lhs.m_state != rhs.m_state);
484 }
485
486 private:
487
488 state_type m_state;
489 };
490
499 class Xoroshiro64StarStar
500 {
501 public:
502
503 using state_type = std::array<std::uint32_t, 2>;
504 using result_type = std::uint32_t;
505
509 explicit constexpr Xoroshiro64StarStar(std::uint64_t seed = DefaultSeed) noexcept;
510
513 template <class SeedSeq,
514 std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>, Xoroshiro64StarStar>>* = nullptr>
516 explicit constexpr Xoroshiro64StarStar(SeedSeq& seq);
517
521 explicit constexpr Xoroshiro64StarStar(state_type state) noexcept;
522
525 constexpr result_type operator()() noexcept;
526
529 constexpr void discard(unsigned long long n) noexcept;
530
533 [[nodiscard]]
534 static constexpr result_type min() noexcept;
535
538 [[nodiscard]]
539 static constexpr result_type max() noexcept;
540
544 [[nodiscard]]
545 constexpr state_type serialize() const noexcept;
546
550 constexpr void deserialize(state_type state) noexcept;
551
552 [[nodiscard]]
553 friend bool operator ==(const Xoroshiro64StarStar& lhs, const Xoroshiro64StarStar& rhs) noexcept
554 {
555 return (lhs.m_state == rhs.m_state);
556 }
557
558 [[nodiscard]]
559 friend bool operator !=(const Xoroshiro64StarStar& lhs, const Xoroshiro64StarStar& rhs) noexcept
560 {
561 return (lhs.m_state != rhs.m_state);
562 }
563
564 private:
565
566 state_type m_state;
567 };
576 class SFC64
577 {
578 public:
579
580 using state_type = std::array<std::uint64_t, 4>;
581 using result_type = std::uint64_t;
582
585 [[nodiscard]]
586 explicit constexpr SFC64(std::uint64_t seed = DefaultSeed) noexcept;
587
590 template <class SeedSeq,
591 std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>, SFC64>>* = nullptr>
593 explicit constexpr SFC64(SeedSeq& seq);
594
597 [[nodiscard]]
598 explicit constexpr SFC64(state_type state) noexcept;
599
602 constexpr result_type operator()() noexcept;
603
606 constexpr void discard(unsigned long long n) noexcept;
607
610 [[nodiscard]]
611 static constexpr result_type min() noexcept;
612
615 [[nodiscard]]
616 static constexpr result_type max() noexcept;
617
621 [[nodiscard]]
622 constexpr state_type serialize() const noexcept;
623
627 constexpr void deserialize(state_type state) noexcept;
628
629 [[nodiscard]]
630 friend bool operator ==(const SFC64& lhs, const SFC64& rhs) noexcept
631 {
632 return (lhs.serialize() == rhs.serialize());
633 }
634
635 [[nodiscard]]
636 friend bool operator !=(const SFC64& lhs, const SFC64& rhs) noexcept
637 {
638 return (lhs.serialize() != rhs.serialize());
639 }
640
641 private:
642
643 std::uint64_t m_a;
644 std::uint64_t m_b;
645 std::uint64_t m_c;
646 std::uint64_t m_counter;
647 };
648
657 class RomuDuoJr
658 {
659 public:
660
661 using state_type = std::array<std::uint64_t, 2>;
662 using result_type = std::uint64_t;
663
666 [[nodiscard]]
667 explicit constexpr RomuDuoJr(std::uint64_t seed = DefaultSeed) noexcept;
668
671 template <class SeedSeq,
672 std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>, RomuDuoJr>>* = nullptr>
674 explicit constexpr RomuDuoJr(SeedSeq& seq);
675
678 [[nodiscard]]
679 explicit constexpr RomuDuoJr(state_type state) noexcept;
680
683 constexpr result_type operator()() noexcept;
684
687 constexpr void discard(unsigned long long n) noexcept;
688
691 [[nodiscard]]
692 static constexpr result_type min() noexcept;
693
696 [[nodiscard]]
697 static constexpr result_type max() noexcept;
698
702 [[nodiscard]]
703 constexpr state_type serialize() const noexcept;
704
708 constexpr void deserialize(state_type state) noexcept;
709
710 [[nodiscard]]
711 friend bool operator ==(const RomuDuoJr& lhs, const RomuDuoJr& rhs) noexcept
712 {
713 return (lhs.serialize() == rhs.serialize());
714 }
715
716 [[nodiscard]]
717 friend bool operator !=(const RomuDuoJr& lhs, const RomuDuoJr& rhs) noexcept
718 {
719 return (lhs.serialize() != rhs.serialize());
720 }
721
722 private:
723
724 std::uint64_t m_x;
725 std::uint64_t m_y;
726 };
727
739 class ChaCha20
740 {
741 public:
742
743 using result_type = std::uint64_t;
744
745 ChaCha20(const ChaCha20&) = delete;
746 ChaCha20& operator=(const ChaCha20&) = delete;
747 ChaCha20(ChaCha20&& other) noexcept;
748 ChaCha20& operator=(ChaCha20&& other) noexcept;
749 ~ChaCha20() noexcept;
750
754
759 explicit ChaCha20(std::uint64_t seed);
760
768 ChaCha20(const std::uint8_t* key, std::size_t keyLen,
769 const std::uint8_t* nonce, std::size_t nonceLen,
770 std::uint32_t counter = 0);
771
774 result_type operator()();
775
778 void discard(unsigned long long n);
779
782 void reseed();
783
787 static constexpr result_type min() noexcept { return 0; }
788
792 static constexpr result_type max() noexcept { return UINT64_MAX; }
793
794 // 不提供:serialize/deserialize, operator<</>>, jump/longJump(CSPRNG 安全约束)
795
796 private:
797
798 std::array<std::uint32_t, 12> m_state; // key(8) + counter(1) + nonce(3),常数省略(generateBlock 时补齐)
799 std::array<std::uint8_t, 64> m_buffer; // 当前 block 的字节缓存
800 std::size_t m_bufferPos; // 缓存消费位置 [0, 64),==64 时触发新 block
801 std::uint64_t m_bytesSinceReseed; // 自上次 reseed 以来输出的字节数
802
803 void generateBlock(); // 跑一次 ChaCha20 block 函数填充 m_buffer
804 void reseedIfNecessary(); // m_bytesSinceReseed >= 阈值时自动 reseed
805 };
806}
807
809
810namespace RandX
811{
812 template <class Uint32, std::enable_if_t<std::is_same_v<Uint32, std::uint32_t>>*>
813 inline constexpr float FloatFromBits(const Uint32 i) noexcept
814 {
815 return (i >> 8) * 0x1.0p-24f;
816 }
817
818 template <class Uint64, std::enable_if_t<std::is_same_v<Uint64, std::uint64_t>>*>
819 inline constexpr double DoubleFromBits(const Uint64 i) noexcept
820 {
821 return (i >> 11) * 0x1.0p-53;
822 }
823
824 namespace detail
825 {
826 [[nodiscard]]
827 static constexpr std::uint64_t RotL(const std::uint64_t x, const int s) noexcept
828 {
829 const int count = s & 63;
830 return count == 0 ? x : ((x << count) | (x >> (64 - count)));
831 }
832
833 [[nodiscard]]
834 static constexpr std::uint32_t RotL(const std::uint32_t x, const int s) noexcept
835 {
836 const int count = s & 31;
837 return count == 0 ? x : ((x << count) | (x >> (32 - count)));
838 }
839
840 // 安全擦除内存(volatile 防止编译器死存储消除)
841 static void SecureWipe(void* ptr, std::size_t len) noexcept
842 {
843 volatile auto* p = static_cast<volatile std::uint8_t*>(ptr);
844 while (len--) *p++ = 0;
845 }
846
847 // 检测状态数组是否全零(全零是 xoshiro/xoroshiro 的吸收态)
848 template <std::size_t N>
849 [[nodiscard]]
850 static constexpr bool IsAllZero(const std::array<std::uint64_t, N>& state) noexcept
851 {
852 for (const auto& s : state) { if (s != 0) return false; }
853 return true;
854 }
855
856 template <std::size_t N>
857 [[nodiscard]]
858 static constexpr bool IsAllZero(const std::array<std::uint32_t, N>& state) noexcept
859 {
860 for (const auto& s : state) { if (s != 0) return false; }
861 return true;
862 }
863
864 // 尝试使用 RDRAND 获取 64 位硬件随机数
865 [[nodiscard]]
866 inline bool HardwareRand64(std::uint64_t& out) noexcept
867 {
868#if defined(__x86_64__) || defined(_M_X64)
869 #if defined(__RDRND__)
870 unsigned long long result;
871 if (__builtin_ia32_rdrand64_step(&result))
872 {
873 out = result;
874 return true;
875 }
876 #elif defined(_MSC_VER)
877 unsigned long long result;
878 if (_rdrand64_step(&result))
879 {
880 out = result;
881 return true;
882 }
883 #endif
884#endif
885 (void)out;
886 return false;
887 }
888
889 // ── A3 跨平台 OS 密码学熵源 ──
890 // 用 OS 密码学 API 填充 [buf, buf+n) 字节;成功返回 true。
891 // 平台优先级:Windows BCryptGenRandom → Linux getrandom → macOS SecRandomCopyBytes → std::random_device 兜底
892 // 注:getrandom 可能短读,内部循环直至填满;BCryptGenRandom/SecRandomCopyBytes 一次填满
893 [[nodiscard]]
894 inline bool GetOsEntropyBytes(void* buf, std::size_t n) noexcept
895 {
896 if (n == 0) return true;
897 auto* p = static_cast<std::uint8_t*>(buf);
898
899# if defined(_WIN32) && __has_include(<bcrypt.h>)
900 // Windows: BCryptGenRandom(分块处理 >4GB 时的 ULONG 截断)
901 // NTSTATUS >= 0 即 NT_SUCCESS(不能 == 0,正向 informational code 也属成功)
902 std::size_t filled = 0;
903 while (filled < n)
904 {
905 const ULONG chunkSize = static_cast<ULONG>((std::min)(n - filled, static_cast<std::size_t>((std::numeric_limits<ULONG>::max)())));
906 if (::BCryptGenRandom(nullptr, p + filled, chunkSize, BCRYPT_USE_SYSTEM_PREFERRED_RNG) < 0)
907 {
908 return false;
909 }
910 filled += chunkSize;
911 }
912 return true;
913
914# elif defined(__linux__) && __has_include(<sys/random.h>)
915 // Linux: getrandom(循环处理短读与 EINTR)
916 std::size_t filled = 0;
917 while (filled < n)
918 {
919 const ssize_t ret = ::getrandom(p + filled, n - filled, 0);
920 if (ret < 0)
921 {
922 if (errno == EINTR) continue; // 被信号打断,重试
923 return false; // ENOSYS/EFAULT 等不可恢复错误
924 }
925 if (ret == 0) return false;
926 filled += static_cast<std::size_t>(ret);
927 }
928 return true;
929
930# elif defined(__APPLE__) && __has_include(<Security/Security.h>)
931 // macOS: SecRandomCopyBytes(一次调用填满)
932 return (::SecRandomCopyBytes(kSecRandomDefault, n, p) == errSecSuccess);
933
934# else
935 // 无可用 OS 密码学熵源 → 返回 false,SecureRandomBytes 将抛出异常
936 // 非安全场景的播种请使用 RandomSeed()(含 random_device → 时间戳回退链)
937 (void)p; (void)n;
938 return false;
939# endif
940 }
941
942 // 返回 true 当且仅当编译期检测到 OS 密码学熵源 API(BCryptGenRandom/getrandom/SecRandomCopyBytes)
943 // 返回 false 表示当前运行在 std::random_device 兜底路径,ChaCha20() 默认构造不保证密码学安全
944 [[nodiscard]]
945 inline bool HasCryptoGradeOsEntropy() noexcept
946 {
947# if (defined(_WIN32) && __has_include(<bcrypt.h>)) || (defined(__linux__) && __has_include(<sys/random.h>)) || (defined(__APPLE__) && __has_include(<Security/Security.h>))
948 return true;
949# else
950 return false;
951# endif
952 }
953
954 // ── A4 ChaCha20 常数与辅助 ──
955 // ChaCha20 常数 "expand 32-byte k"(RFC 8439 §2.3)
956 inline constexpr std::uint32_t ChaCha20Constants[4] = {
957 0x61707865u, 0x3320646eu, 0x79622d32u, 0x6b206574u
958 };
959 // 参考 NIST SP 800-90A reseed_interval 概念(SP 800-90A 涵盖 Hash/HMAC/CTR_DRBG,不含 ChaCha20;
960 // 此处借用其"周期性强制 reseed 提供前向安全"思想,取保守阈值)
961 inline constexpr std::uint64_t ChaCha20ReseedThreshold = 1ULL << 20; // 1 MB
962
963 // ChaCha20 quarter-round(仅 add/xor/rotl,常时间友好)
964 static void ChaCha20QuarterRound(std::uint32_t& a, std::uint32_t& b,
965 std::uint32_t& c, std::uint32_t& d) noexcept
966 {
967 a += b; d ^= a; d = RotL(d, 16);
968 c += d; b ^= c; b = RotL(b, 12);
969 a += b; d ^= a; d = RotL(d, 8);
970 c += d; b ^= c; b = RotL(b, 7);
971 }
972 }
973
975 //
976 // SplitMix64
977 //
978 inline constexpr SplitMix64::SplitMix64(const state_type state) noexcept
979 : m_state(state) {}
980
981 template <class SeedSeq, std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>, SplitMix64>>*>
982 inline constexpr SplitMix64::SplitMix64(SeedSeq& seq)
983 {
984 std::array<std::uint32_t, 2> seeds;
985 seq.generate(seeds.begin(), seeds.end());
986 m_state = (static_cast<std::uint64_t>(seeds[0]) << 32) | seeds[1];
987 }
988
989 inline constexpr SplitMix64::result_type SplitMix64::operator()() noexcept
990 {
991 std::uint64_t z = (m_state += 0x9e3779b97f4a7c15);
992 z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
993 z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
994 return z ^ (z >> 31);
995 }
996
997 template <std::size_t N>
998 inline constexpr std::array<std::uint64_t, N> SplitMix64::generateSeedSequence() noexcept
999 {
1000 std::array<std::uint64_t, N> seeds = {};
1001
1002 for (auto& seed : seeds)
1003 {
1004 seed = operator()();
1005 }
1006
1007 return seeds;
1008 }
1009
1010 inline constexpr SplitMix64::result_type SplitMix64::min() noexcept
1011 {
1012 return std::numeric_limits<result_type>::lowest();
1013 }
1014
1015 inline constexpr SplitMix64::result_type SplitMix64::max() noexcept
1016 {
1017 return std::numeric_limits<result_type>::max();
1018 }
1019
1020 inline constexpr SplitMix64::state_type SplitMix64::serialize() const noexcept
1021 {
1022 return m_state;
1023 }
1024
1025 inline constexpr void SplitMix64::deserialize(const state_type state) noexcept
1026 {
1027 m_state = state;
1028 }
1029
1030 inline constexpr void SplitMix64::discard(const unsigned long long n) noexcept
1031 {
1032 for (unsigned long long i = 0; i < n; ++i) { operator()(); }
1033 }
1034
1036 //
1037 // xoshiro256**
1038 //
1039 inline constexpr Xoshiro256StarStar::Xoshiro256StarStar(const std::uint64_t seed) noexcept
1040 : m_state(SplitMix64{ seed }.generateSeedSequence<4>())
1041 {
1042 if (detail::IsAllZero(m_state)) m_state[0] = 1;
1043 }
1044
1045 template <class SeedSeq, std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>, Xoshiro256StarStar>>*>
1046 inline constexpr Xoshiro256StarStar::Xoshiro256StarStar(SeedSeq& seq)
1047 {
1048 std::array<std::uint32_t, 8> seeds;
1049 seq.generate(seeds.begin(), seeds.end());
1050 for (int i = 0; i < 4; ++i)
1051 m_state[i] = (static_cast<std::uint64_t>(seeds[2*i]) << 32) | seeds[2*i+1];
1052 if (detail::IsAllZero(m_state)) m_state[0] = 1;
1053 }
1054
1055 inline constexpr Xoshiro256StarStar::Xoshiro256StarStar(const state_type state) noexcept
1056 : m_state(state)
1057 {
1058 assert(!detail::IsAllZero(state) && "全零状态是吸收态,禁止使用");
1059 }
1060
1062 {
1063 const std::uint64_t result = detail::RotL(m_state[1] * 5, 7) * 9;
1064 const std::uint64_t t = m_state[1] << 17;
1065 m_state[2] ^= m_state[0];
1066 m_state[3] ^= m_state[1];
1067 m_state[1] ^= m_state[2];
1068 m_state[0] ^= m_state[3];
1069 m_state[2] ^= t;
1070 m_state[3] = detail::RotL(m_state[3], 45);
1071 return result;
1072 }
1073
1074 inline constexpr void Xoshiro256StarStar::jump() noexcept
1075 {
1076 constexpr std::uint64_t JUMP[] = { 0x180ec6d33cfd0aba, 0xd5a61266f0c9392c, 0xa9582618e03fc9aa, 0x39abdc4529b1661c };
1077
1078 std::uint64_t s0 = 0;
1079 std::uint64_t s1 = 0;
1080 std::uint64_t s2 = 0;
1081 std::uint64_t s3 = 0;
1082
1083 for (std::uint64_t j : JUMP)
1084 {
1085 for (int b = 0; b < 64; ++b)
1086 {
1087 if (j & UINT64_C(1) << b)
1088 {
1089 s0 ^= m_state[0];
1090 s1 ^= m_state[1];
1091 s2 ^= m_state[2];
1092 s3 ^= m_state[3];
1093 }
1094 operator()();
1095 }
1096 }
1097
1098 m_state[0] = s0;
1099 m_state[1] = s1;
1100 m_state[2] = s2;
1101 m_state[3] = s3;
1102 }
1103
1104 inline constexpr void Xoshiro256StarStar::longJump() noexcept
1105 {
1106 constexpr std::uint64_t LONG_JUMP[] = { 0x76e15d3efefdcbbf, 0xc5004e441c522fb3, 0x77710069854ee241, 0x39109bb02acbe635 };
1107
1108 std::uint64_t s0 = 0;
1109 std::uint64_t s1 = 0;
1110 std::uint64_t s2 = 0;
1111 std::uint64_t s3 = 0;
1112
1113 for (std::uint64_t j : LONG_JUMP)
1114 {
1115 for (int b = 0; b < 64; ++b)
1116 {
1117 if (j & UINT64_C(1) << b)
1118 {
1119 s0 ^= m_state[0];
1120 s1 ^= m_state[1];
1121 s2 ^= m_state[2];
1122 s3 ^= m_state[3];
1123 }
1124 operator()();
1125 }
1126 }
1127
1128 m_state[0] = s0;
1129 m_state[1] = s1;
1130 m_state[2] = s2;
1131 m_state[3] = s3;
1132 }
1133
1135 {
1136 return std::numeric_limits<result_type>::lowest();
1137 }
1138
1140 {
1141 return std::numeric_limits<result_type>::max();
1142 }
1143
1144 inline constexpr Xoshiro256StarStar::state_type Xoshiro256StarStar::serialize() const noexcept
1145 {
1146 return m_state;
1147 }
1148
1149 inline constexpr void Xoshiro256StarStar::deserialize(const state_type state) noexcept
1150 {
1151 assert(!detail::IsAllZero(state) && "全零状态是吸收态,禁止使用");
1152 m_state = state;
1153 }
1154
1155 inline constexpr void Xoshiro256StarStar::discard(const unsigned long long n) noexcept
1156 {
1157 for (unsigned long long i = 0; i < n; ++i) { operator()(); }
1158 }
1159
1161 //
1162 // xoroshiro128**
1163 //
1164 inline constexpr Xoroshiro128StarStar::Xoroshiro128StarStar(const std::uint64_t seed) noexcept
1165 : m_state(SplitMix64{ seed }.generateSeedSequence<2>())
1166 {
1167 if (detail::IsAllZero(m_state)) m_state[0] = 1;
1168 }
1169
1170 template <class SeedSeq, std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>, Xoroshiro128StarStar>>*>
1171 inline constexpr Xoroshiro128StarStar::Xoroshiro128StarStar(SeedSeq& seq)
1172 {
1173 std::array<std::uint32_t, 4> seeds;
1174 seq.generate(seeds.begin(), seeds.end());
1175 m_state[0] = (static_cast<std::uint64_t>(seeds[0]) << 32) | seeds[1];
1176 m_state[1] = (static_cast<std::uint64_t>(seeds[2]) << 32) | seeds[3];
1177 if (detail::IsAllZero(m_state)) m_state[0] = 1;
1178 }
1179
1180 inline constexpr Xoroshiro128StarStar::Xoroshiro128StarStar(const state_type state) noexcept
1181 : m_state(state)
1182 {
1183 assert(!detail::IsAllZero(state) && "全零状态是吸收态,禁止使用");
1184 }
1185
1187 {
1188 const std::uint64_t s0 = m_state[0];
1189 std::uint64_t s1 = m_state[1];
1190 const std::uint64_t result = detail::RotL(s0 * 5, 7) * 9;
1191 s1 ^= s0;
1192 m_state[0] = detail::RotL(s0, 24) ^ s1 ^ (s1 << 16);
1193 m_state[1] = detail::RotL(s1, 37);
1194 return result;
1195 }
1196
1197 inline constexpr void Xoroshiro128StarStar::jump() noexcept
1198 {
1199 constexpr std::uint64_t JUMP[] = { 0xdf900294d8f554a5, 0x170865df4b3201fc };
1200
1201 std::uint64_t s0 = 0;
1202 std::uint64_t s1 = 0;
1203
1204 for (std::uint64_t j : JUMP)
1205 {
1206 for (int b = 0; b < 64; ++b)
1207 {
1208 if (j & UINT64_C(1) << b)
1209 {
1210 s0 ^= m_state[0];
1211 s1 ^= m_state[1];
1212 }
1213 operator()();
1214 }
1215 }
1216
1217 m_state[0] = s0;
1218 m_state[1] = s1;
1219 }
1220
1221 inline constexpr void Xoroshiro128StarStar::longJump() noexcept
1222 {
1223 constexpr std::uint64_t LONG_JUMP[] = { 0xd2a98b26625eee7b, 0xdddf9b1090aa7ac1 };
1224
1225 std::uint64_t s0 = 0;
1226 std::uint64_t s1 = 0;
1227
1228 for (std::uint64_t j : LONG_JUMP)
1229 {
1230 for (int b = 0; b < 64; ++b)
1231 {
1232 if (j & UINT64_C(1) << b)
1233 {
1234 s0 ^= m_state[0];
1235 s1 ^= m_state[1];
1236 }
1237 operator()();
1238 }
1239 }
1240
1241 m_state[0] = s0;
1242 m_state[1] = s1;
1243 }
1244
1246 {
1247 return std::numeric_limits<result_type>::lowest();
1248 }
1249
1251 {
1252 return std::numeric_limits<result_type>::max();
1253 }
1254
1256 {
1257 return m_state;
1258 }
1259
1260 inline constexpr void Xoroshiro128StarStar::deserialize(const state_type state) noexcept
1261 {
1262 assert(!detail::IsAllZero(state) && "全零状态是吸收态,禁止使用");
1263 m_state = state;
1264 }
1265
1266 inline constexpr void Xoroshiro128StarStar::discard(const unsigned long long n) noexcept
1267 {
1268 for (unsigned long long i = 0; i < n; ++i) { operator()(); }
1269 }
1270
1272 //
1273 // xoshiro128**
1274 //
1275 inline constexpr Xoshiro128StarStar::Xoshiro128StarStar(const std::uint64_t seed) noexcept
1276 : m_state()
1277 {
1278 SplitMix64 splitmix{ seed };
1279
1280 for (auto& state : m_state)
1281 {
1282 state = static_cast<std::uint32_t>(splitmix());
1283 }
1284 if (detail::IsAllZero(m_state)) m_state[0] = 1;
1285 }
1286
1287 template <class SeedSeq, std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>, Xoshiro128StarStar>>*>
1288 inline constexpr Xoshiro128StarStar::Xoshiro128StarStar(SeedSeq& seq)
1289 {
1290 std::array<std::uint32_t, 4> seeds;
1291 seq.generate(seeds.begin(), seeds.end());
1292 m_state = seeds;
1293 if (detail::IsAllZero(m_state)) m_state[0] = 1;
1294 }
1295
1296 inline constexpr Xoshiro128StarStar::Xoshiro128StarStar(const state_type state) noexcept
1297 : m_state(state)
1298 {
1299 assert(!detail::IsAllZero(state) && "全零状态是吸收态,禁止使用");
1300 }
1301
1303 {
1304 const std::uint32_t result = detail::RotL(m_state[1] * 5, 7) * 9;
1305 const std::uint32_t t = m_state[1] << 9;
1306 m_state[2] ^= m_state[0];
1307 m_state[3] ^= m_state[1];
1308 m_state[1] ^= m_state[2];
1309 m_state[0] ^= m_state[3];
1310 m_state[2] ^= t;
1311 m_state[3] = detail::RotL(m_state[3], 11);
1312 return result;
1313 }
1314
1315 inline constexpr void Xoshiro128StarStar::jump() noexcept
1316 {
1317 constexpr std::uint32_t JUMP[] = { 0x8764000b, 0xf542d2d3, 0x6fa035c3, 0x77f2db5b };
1318
1319 std::uint32_t s0 = 0;
1320 std::uint32_t s1 = 0;
1321 std::uint32_t s2 = 0;
1322 std::uint32_t s3 = 0;
1323
1324 for (std::uint32_t j : JUMP)
1325 {
1326 for (int b = 0; b < 32; ++b)
1327 {
1328 if (j & UINT32_C(1) << b)
1329 {
1330 s0 ^= m_state[0];
1331 s1 ^= m_state[1];
1332 s2 ^= m_state[2];
1333 s3 ^= m_state[3];
1334 }
1335 operator()();
1336 }
1337 }
1338
1339 m_state[0] = s0;
1340 m_state[1] = s1;
1341 m_state[2] = s2;
1342 m_state[3] = s3;
1343 }
1344
1345 inline constexpr void Xoshiro128StarStar::longJump() noexcept
1346 {
1347 constexpr std::uint32_t LONG_JUMP[] = { 0xb523952e, 0x0b6f099f, 0xccf5a0ef, 0x1c580662 };
1348
1349 std::uint32_t s0 = 0;
1350 std::uint32_t s1 = 0;
1351 std::uint32_t s2 = 0;
1352 std::uint32_t s3 = 0;
1353
1354 for (std::uint32_t j : LONG_JUMP)
1355 {
1356 for (int b = 0; b < 32; ++b)
1357 {
1358 if (j & UINT32_C(1) << b)
1359 {
1360 s0 ^= m_state[0];
1361 s1 ^= m_state[1];
1362 s2 ^= m_state[2];
1363 s3 ^= m_state[3];
1364 }
1365 operator()();
1366 }
1367 }
1368
1369 m_state[0] = s0;
1370 m_state[1] = s1;
1371 m_state[2] = s2;
1372 m_state[3] = s3;
1373 }
1374
1376 {
1377 return std::numeric_limits<result_type>::lowest();
1378 }
1379
1381 {
1382 return std::numeric_limits<result_type>::max();
1383 }
1384
1385 inline constexpr Xoshiro128StarStar::state_type Xoshiro128StarStar::serialize() const noexcept
1386 {
1387 return m_state;
1388 }
1389
1390 inline constexpr void Xoshiro128StarStar::deserialize(const state_type state) noexcept
1391 {
1392 assert(!detail::IsAllZero(state) && "全零状态是吸收态,禁止使用");
1393 m_state = state;
1394 }
1395
1396 inline constexpr void Xoshiro128StarStar::discard(const unsigned long long n) noexcept
1397 {
1398 for (unsigned long long i = 0; i < n; ++i) { operator()(); }
1399 }
1400
1402 //
1403 // xoroshiro64**
1404 //
1405 inline constexpr Xoroshiro64StarStar::Xoroshiro64StarStar(const std::uint64_t seed) noexcept
1406 : m_state()
1407 {
1408 SplitMix64 splitmix{ seed };
1409
1410 for (auto& state : m_state)
1411 {
1412 state = static_cast<std::uint32_t>(splitmix());
1413 }
1414 if (detail::IsAllZero(m_state)) m_state[0] = 1;
1415 }
1416
1417 template <class SeedSeq, std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>, Xoroshiro64StarStar>>*>
1418 inline constexpr Xoroshiro64StarStar::Xoroshiro64StarStar(SeedSeq& seq)
1419 {
1420 std::array<std::uint32_t, 2> seeds;
1421 seq.generate(seeds.begin(), seeds.end());
1422 m_state = seeds;
1423 if (detail::IsAllZero(m_state)) m_state[0] = 1;
1424 }
1425
1426 inline constexpr Xoroshiro64StarStar::Xoroshiro64StarStar(const state_type state) noexcept
1427 : m_state(state)
1428 {
1429 assert(!detail::IsAllZero(state) && "全零状态是吸收态,禁止使用");
1430 }
1431
1433 {
1434 const std::uint32_t s0 = m_state[0];
1435 std::uint32_t s1 = m_state[1];
1436
1437 const std::uint32_t result = detail::RotL(s0 * 0x9E3779BB, 5) * 5;
1438
1439 s1 ^= s0;
1440 m_state[0] = detail::RotL(s0, 26) ^ s1 ^ (s1 << 9);
1441 m_state[1] = detail::RotL(s1, 13);
1442
1443 return result;
1444 }
1445
1447 {
1448 return std::numeric_limits<result_type>::lowest();
1449 }
1450
1452 {
1453 return std::numeric_limits<result_type>::max();
1454 }
1455
1456 inline constexpr Xoroshiro64StarStar::state_type Xoroshiro64StarStar::serialize() const noexcept
1457 {
1458 return m_state;
1459 }
1460
1461 inline constexpr void Xoroshiro64StarStar::deserialize(const state_type state) noexcept
1462 {
1463 assert(!detail::IsAllZero(state) && "全零状态是吸收态,禁止使用");
1464 m_state = state;
1465 }
1466
1467 inline constexpr void Xoroshiro64StarStar::discard(const unsigned long long n) noexcept
1468 {
1469 for (unsigned long long i = 0; i < n; ++i) { operator()(); }
1470 }
1471
1473 //
1474 // SFC64 (Small Fast Counter)
1475 //
1476 inline constexpr SFC64::SFC64(const std::uint64_t seed) noexcept
1477 : m_a(0), m_b(0), m_c(0), m_counter(1)
1478 {
1479 // 使用 SplitMix64 播种 + 12 轮预热
1480 SplitMix64 sm{ seed };
1481 m_a = sm();
1482 m_b = sm();
1483 m_c = sm();
1484 for (int i = 0; i < 12; ++i) { operator()(); }
1485 }
1486
1487 template <class SeedSeq, std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>, SFC64>>*>
1488 inline constexpr SFC64::SFC64(SeedSeq& seq)
1489 : m_counter(1)
1490 {
1491 std::array<std::uint32_t, 8> seeds;
1492 seq.generate(seeds.begin(), seeds.end());
1493 m_a = (static_cast<std::uint64_t>(seeds[0]) << 32) | seeds[1];
1494 m_b = (static_cast<std::uint64_t>(seeds[2]) << 32) | seeds[3];
1495 m_c = (static_cast<std::uint64_t>(seeds[4]) << 32) | seeds[5];
1496 // 全零状态会导致输出可预测,强制修正
1497 if ((m_a | m_b | m_c) == 0) m_a = 0x9E3779B97F4A7C15ULL;
1498 // 与种子构造函数一致:12 轮预热
1499 for (int i = 0; i < 12; ++i) { operator()(); }
1500 }
1501
1502 inline constexpr SFC64::SFC64(const state_type state) noexcept
1503 : m_a(state[0]), m_b(state[1]), m_c(state[2]), m_counter(state[3]) {}
1504
1505 inline constexpr SFC64::result_type SFC64::operator()() noexcept
1506 {
1507 const std::uint64_t tmp = m_a + m_b + m_counter++;
1508 m_a = m_b ^ (m_b >> 11);
1509 m_b = m_c + (m_c << 3);
1510 m_c = detail::RotL(m_c, 24) + tmp;
1511 return tmp;
1512 }
1513
1514 inline constexpr SFC64::result_type SFC64::min() noexcept
1515 {
1516 return std::numeric_limits<result_type>::lowest();
1517 }
1518
1519 inline constexpr SFC64::result_type SFC64::max() noexcept
1520 {
1521 return std::numeric_limits<result_type>::max();
1522 }
1523
1524 inline constexpr SFC64::state_type SFC64::serialize() const noexcept
1525 {
1526 return { m_a, m_b, m_c, m_counter };
1527 }
1528
1529 inline constexpr void SFC64::deserialize(const state_type state) noexcept
1530 {
1531 m_a = state[0];
1532 m_b = state[1];
1533 m_c = state[2];
1534 m_counter = state[3];
1535 }
1536
1537 inline constexpr void SFC64::discard(const unsigned long long n) noexcept
1538 {
1539 for (unsigned long long i = 0; i < n; ++i) { operator()(); }
1540 }
1541
1543 //
1544 // RomuDuoJr
1545 //
1546 inline constexpr RomuDuoJr::RomuDuoJr(const std::uint64_t seed) noexcept
1547 : m_x(0), m_y(0)
1548 {
1549 SplitMix64 sm{ seed };
1550 m_x = sm();
1551 m_y = sm();
1552 // 确保不全零
1553 if (m_x == 0 && m_y == 0) { m_x = 1; }
1554 }
1555
1556 template <class SeedSeq, std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>, RomuDuoJr>>*>
1557 inline constexpr RomuDuoJr::RomuDuoJr(SeedSeq& seq)
1558 {
1559 std::array<std::uint32_t, 4> seeds;
1560 seq.generate(seeds.begin(), seeds.end());
1561 m_x = (static_cast<std::uint64_t>(seeds[0]) << 32) | seeds[1];
1562 m_y = (static_cast<std::uint64_t>(seeds[2]) << 32) | seeds[3];
1563 if (m_x == 0 && m_y == 0) m_x = 1;
1564 }
1565
1566 inline constexpr RomuDuoJr::RomuDuoJr(const state_type state) noexcept
1567 : m_x(state[0]), m_y(state[1])
1568 {
1569 assert(!(m_x == 0 && m_y == 0) && "全零状态是吸收态,禁止使用");
1570 }
1571
1572 inline constexpr RomuDuoJr::result_type RomuDuoJr::operator()() noexcept
1573 {
1574 const std::uint64_t xp = m_x;
1575 m_x = 15241094284759029579ULL * m_y;
1576 m_y = detail::RotL(m_y - xp, 27);
1577 return xp;
1578 }
1579
1580 inline constexpr RomuDuoJr::result_type RomuDuoJr::min() noexcept
1581 {
1582 return std::numeric_limits<result_type>::lowest();
1583 }
1584
1585 inline constexpr RomuDuoJr::result_type RomuDuoJr::max() noexcept
1586 {
1587 return std::numeric_limits<result_type>::max();
1588 }
1589
1590 inline constexpr RomuDuoJr::state_type RomuDuoJr::serialize() const noexcept
1591 {
1592 return { m_x, m_y };
1593 }
1594
1595 inline constexpr void RomuDuoJr::deserialize(const state_type state) noexcept
1596 {
1597 assert(!(state[0] == 0 && state[1] == 0) && "全零状态是吸收态,禁止使用");
1598 m_x = state[0];
1599 m_y = state[1];
1600 }
1601
1602 inline constexpr void RomuDuoJr::discard(const unsigned long long n) noexcept
1603 {
1604 for (unsigned long long i = 0; i < n; ++i) { operator()(); }
1605 }
1606
1608 //
1609 // 多流接口(并行计算)
1610 //
1611
1612 // 从同一种子创建第 streamId 个不重叠子序列的引擎
1613 // 每个流之间间隔 2^128 步(xoshiro256)或 2^64 步(xoroshiro128/xoshiro128)
1614 // 注意:Xoroshiro64 系列无 jump 函数,不支持多流
1615 namespace detail
1616 {
1617 template <class Engine, class = void>
1618 struct HasJump : std::false_type {};
1619 template <class Engine>
1620 struct HasJump<Engine, std::void_t<decltype(std::declval<Engine&>().jump())>> : std::true_type {};
1621 }
1622
1623 namespace detail
1624 {
1625 // 字符类型检测(char/wchar_t/char16_t/char32_t,C++20+ 追加 char8_t)
1626 template <class T>
1627 struct is_character : std::bool_constant<
1628 std::is_same_v<T, char>
1629 || std::is_same_v<T, wchar_t>
1630 || std::is_same_v<T, char16_t>
1631 || std::is_same_v<T, char32_t>
1632# if defined(__cpp_char8_t) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
1633 || std::is_same_v<T, char8_t>
1634# endif
1635 > {};
1636
1637 template <class T>
1639
1640 // 检测 It 是否为 random_access 迭代器(void_t 包装避免硬错误)
1641 template <class It, class = void>
1642 struct is_random_access_iterator : std::false_type {};
1643
1644 template <class It>
1645 struct is_random_access_iterator<It, std::void_t<
1646 typename std::iterator_traits<It>::iterator_category>>
1647 : std::is_base_of<std::random_access_iterator_tag,
1648 typename std::iterator_traits<It>::iterator_category> {};
1649
1650 // 检测 It 是否为 input_iterator(正向检测,自动排除 output_iterator_tag)
1651 template <class It, class = void>
1652 struct is_input_iterator : std::false_type {};
1653
1654 template <class It>
1655 struct is_input_iterator<It, std::void_t<
1656 typename std::iterator_traits<It>::iterator_category>>
1657 : std::is_base_of<std::input_iterator_tag,
1658 typename std::iterator_traits<It>::iterator_category> {};
1659
1660 template <class It>
1661 inline constexpr bool is_random_access_iterator_v =
1663
1664 template <class It>
1665 inline constexpr bool is_input_iterator_v =
1667
1668 // 检测 C 是否为 random_access 容器
1669 template <class C, class = void>
1670 struct is_random_access_container : std::false_type {};
1671
1672 template <class C>
1673 struct is_random_access_container<C, std::void_t<
1674 decltype(std::begin(std::declval<C&>())),
1675 decltype(std::end(std::declval<C&>()))>>
1676 : is_random_access_iterator<decltype(std::begin(std::declval<C&>()))> {};
1677
1678 template <class C>
1679 inline constexpr bool is_random_access_container_v =
1681
1682 template <class Engine>
1683 [[nodiscard]]
1684 inline std::uint64_t Generate64Bits(Engine& engine)
1685 {
1686 if (sizeof(typename Engine::result_type) >= 8)
1687 {
1688 return static_cast<std::uint64_t>(engine());
1689 }
1690 const std::uint64_t lo = static_cast<std::uint64_t>(engine());
1691 const std::uint64_t hi = static_cast<std::uint64_t>(engine());
1692 return (hi << 32) | lo;
1693 }
1694
1695 // 检测 *first = T 合法性 + T 为数值类型(RandFill 用)
1696 template <class It, class T, class = void>
1697 struct is_rand_fillable : std::false_type {};
1698
1699 template <class It, class T>
1700 struct is_rand_fillable<It, T, std::void_t<
1701 decltype(*std::declval<It&>() = std::declval<T>())
1702 >> : std::bool_constant<
1703 std::is_integral_v<T> || std::is_floating_point_v<T>
1704 > {};
1705
1706 template <class It, class T>
1708
1709 // 检测 state_type 是否为可索引容器(排除标量如 SplitMix64 的 uint64_t)
1710 template <class S, class = void>
1711 struct is_indexable_state : std::false_type {};
1712
1713 template <class S>
1714 struct is_indexable_state<S, std::void_t<
1715 decltype(std::declval<const S&>().size()),
1716 decltype(std::declval<S&>()[std::size_t{}]),
1717 typename S::value_type
1718 >> : std::is_same<
1719 decltype(std::declval<const S&>().size()),
1720 std::size_t> {};
1721
1722 template <class S>
1724
1725 // 可序列化引擎检测(serialize/deserialize/state_type + state_type 为可索引容器)
1726 template <class E, class = void>
1727 struct is_serializable_engine : std::false_type {};
1728
1729 template <class E>
1730 struct is_serializable_engine<E, std::void_t<
1731 decltype(std::declval<const E&>().serialize()),
1732 decltype(std::declval<E&>().deserialize(
1733 std::declval<typename E::state_type>())),
1734 typename E::state_type
1735 >> : std::bool_constant<
1736 std::is_same_v<
1737 decltype(std::declval<const E&>().serialize()),
1738 typename E::state_type>
1739 && is_indexable_state_v<typename E::state_type>
1740 > {};
1741
1742 template <class E>
1744 }
1745
1746 template <class Engine, std::enable_if_t<detail::HasJump<Engine>::value>* = nullptr>
1747 [[nodiscard]]
1748 inline constexpr Engine MakeStreamEngine(std::uint64_t streamId, std::uint64_t seed = DefaultSeed)
1749 {
1750 Engine rng{ seed };
1751 for (std::uint64_t i = 0; i < streamId; ++i)
1752 rng.jump();
1753 return rng;
1754 }
1755
1757 //
1758 // 便捷工具函数
1759 //
1760
1761 // 生成非确定性的 64 位种子(优先硬件 RNG,用于统计 PRNG 播种)
1762 // 优先级链:RDRAND (x86_64) → detail::GetOsEntropyBytes → std::random_device → 时间戳回退
1763 [[nodiscard]]
1764 inline std::uint64_t RandomSeed()
1765 {
1766 std::uint64_t hw;
1767 if (detail::HardwareRand64(hw))
1768 return hw;
1769 if (detail::GetOsEntropyBytes(&hw, sizeof(hw)))
1770 return hw;
1771 std::random_device rd;
1772 try
1773 {
1774 return (static_cast<std::uint64_t>(rd()) << 32) | rd();
1775 }
1776 catch (...)
1777 {
1778 // 最终兜底:时间戳(非密码学,仅保证 RandomSeed 永不抛异常)
1779 return static_cast<std::uint64_t>(std::chrono::system_clock::now().time_since_epoch().count());
1780 }
1781 }
1782
1783 // 默认线程局部引擎,使用 RandomSeed() 播种(含 RDRAND → OS API → random_device → 时间戳回退链)
1784 [[nodiscard]]
1786 {
1787 thread_local Xoshiro256StarStar engine{ RandomSeed() };
1788 return engine;
1789 }
1790
1793
1798 inline void SecureRandomBytes(void* buf, std::size_t n)
1799 {
1800 if (n == 0) return;
1801 if (!detail::GetOsEntropyBytes(buf, n))
1802 throw std::runtime_error("SecureRandomBytes: OS entropy source failed");
1803 }
1804
1807 [[nodiscard]]
1808 inline std::uint64_t SecureSeed()
1809 {
1810 std::uint64_t seed;
1811 SecureRandomBytes(&seed, sizeof(seed));
1812 return seed;
1813 }
1814
1818 [[nodiscard]]
1819 inline bool IsOsCryptoEntropyAvailable() noexcept
1820 {
1822 }
1823
1825 //
1826 // ChaCha20 (RFC 8439) — CSPRNG 引擎实现
1827 //
1828 // 状态矩阵布局(16 × uint32,常数省略存于 m_state[0..11]):
1829 // 0 1 2 3 "expa" "nd 3" "2-by" "te k" ← 常数(generateBlock 时补齐)
1830 // 4 5 6 7 key[0] key[1] key[2] key[3] ← m_state[0..3]
1831 // 8 9 10 11 key[4] key[5] key[6] key[7] ← m_state[4..7]
1832 // 12 13 14 15 ctr nonce[0] nonce[1] nonce[2]← m_state[8..11]
1833 //
1834 // 生成流程:operator() → reseedIfNecessary → (缓存耗尽时)generateBlock → 取 8 字节
1835 //
1836
1837 inline ChaCha20::ChaCha20(ChaCha20&& other) noexcept
1838 : m_state(other.m_state),
1839 m_buffer(other.m_buffer),
1840 m_bufferPos(other.m_bufferPos),
1841 m_bytesSinceReseed(other.m_bytesSinceReseed)
1842 {
1843 detail::SecureWipe(other.m_state.data(), sizeof(other.m_state));
1844 detail::SecureWipe(other.m_buffer.data(), sizeof(other.m_buffer));
1845 other.m_bufferPos = 64;
1846 other.m_bytesSinceReseed = 0;
1847 }
1848
1849 inline ChaCha20& ChaCha20::operator=(ChaCha20&& other) noexcept
1850 {
1851 if (this != &other)
1852 {
1853 detail::SecureWipe(m_state.data(), sizeof(m_state));
1854 detail::SecureWipe(m_buffer.data(), sizeof(m_buffer));
1855
1856 m_state = other.m_state;
1857 m_buffer = other.m_buffer;
1858 m_bufferPos = other.m_bufferPos;
1859 m_bytesSinceReseed = other.m_bytesSinceReseed;
1860
1861 detail::SecureWipe(other.m_state.data(), sizeof(other.m_state));
1862 detail::SecureWipe(other.m_buffer.data(), sizeof(other.m_buffer));
1863 other.m_bufferPos = 64;
1864 other.m_bytesSinceReseed = 0;
1865 }
1866 return *this;
1867 }
1868
1869 inline ChaCha20::~ChaCha20() noexcept
1870 {
1871 detail::SecureWipe(m_state.data(), sizeof(m_state));
1872 detail::SecureWipe(m_buffer.data(), sizeof(m_buffer));
1873 }
1874
1875 // 构造方式 1:从 OS 熵自动播种(密码学安全,默认)
1876 inline ChaCha20::ChaCha20()
1877 : m_state{}, m_buffer{}, m_bufferPos(64), m_bytesSinceReseed(0)
1878 {
1879 reseed(); // 从 OS 熵获取 key + nonce,重置 counter
1880 }
1881
1882 // 构造方式 2:显式种子(仅测试/复现,非密码学安全)
1883 // 用 SplitMix64 将 64-bit 种子扩展为 32 字节 key + 12 字节 nonce
1884 inline ChaCha20::ChaCha20(const std::uint64_t seed)
1885 : m_state{}, m_buffer{}, m_bufferPos(64), m_bytesSinceReseed(0)
1886 {
1887 SplitMix64 sm{ seed };
1888 // key: 前 4 次 SplitMix64 输出,每次 8 字节按小端序拆为 2 个 uint32
1889 for (int i = 0; i < 4; ++i)
1890 {
1891 const std::uint64_t v = sm();
1892 m_state[i * 2] = static_cast<std::uint32_t>(v);
1893 m_state[i * 2 + 1] = static_cast<std::uint32_t>(v >> 32);
1894 }
1895 // nonce: 第 5 次输出(8 字节)+ 第 6 次输出低 4 字节(丢弃高 4 字节)
1896 {
1897 const std::uint64_t v5 = sm();
1898 m_state[9] = static_cast<std::uint32_t>(v5);
1899 m_state[10] = static_cast<std::uint32_t>(v5 >> 32);
1900 }
1901 m_state[11] = static_cast<std::uint32_t>(sm());
1902 m_state[8] = 0; // counter 初值 = 0
1903 }
1904
1905 // 构造方式 3:直接指定 key + nonce + counter
1906 inline ChaCha20::ChaCha20(const std::uint8_t* key, std::size_t keyLen,
1907 const std::uint8_t* nonce, std::size_t nonceLen,
1908 const std::uint32_t counter)
1909 : m_state{}, m_buffer{}, m_bufferPos(64), m_bytesSinceReseed(0)
1910 {
1911 if (keyLen != 32)
1912 throw std::invalid_argument("ChaCha20: key must be 32 bytes");
1913 if (nonceLen != 12)
1914 throw std::invalid_argument("ChaCha20: nonce must be 12 bytes");
1915 // key → m_state[0..7](小端序)
1916 for (int i = 0; i < 8; ++i)
1917 {
1918 m_state[i] = static_cast<std::uint32_t>(key[i * 4])
1919 | (static_cast<std::uint32_t>(key[i * 4 + 1]) << 8)
1920 | (static_cast<std::uint32_t>(key[i * 4 + 2]) << 16)
1921 | (static_cast<std::uint32_t>(key[i * 4 + 3]) << 24);
1922 }
1923 // nonce → m_state[9..11](小端序)
1924 for (int i = 0; i < 3; ++i)
1925 {
1926 m_state[9 + i] = static_cast<std::uint32_t>(nonce[i * 4])
1927 | (static_cast<std::uint32_t>(nonce[i * 4 + 1]) << 8)
1928 | (static_cast<std::uint32_t>(nonce[i * 4 + 2]) << 16)
1929 | (static_cast<std::uint32_t>(nonce[i * 4 + 3]) << 24);
1930 }
1931 m_state[8] = counter; // counter
1932 }
1933
1934 // 生成一个 ChaCha20 block(64 字节)填充 m_buffer
1935 inline void ChaCha20::generateBlock()
1936 {
1937 // 构造完整 16-word 状态:常数 + key + counter + nonce
1938 std::array<std::uint32_t, 16> state{};
1939 state[0] = detail::ChaCha20Constants[0];
1940 state[1] = detail::ChaCha20Constants[1];
1941 state[2] = detail::ChaCha20Constants[2];
1942 state[3] = detail::ChaCha20Constants[3];
1943 for (int i = 0; i < 8; ++i) state[4 + i] = m_state[i]; // key
1944 state[12] = m_state[8]; // counter
1945 state[13] = m_state[9]; // nonce[0]
1946 state[14] = m_state[10]; // nonce[1]
1947 state[15] = m_state[11]; // nonce[2]
1948
1949 std::array<std::uint32_t, 16> working = state;
1950
1951 // 20 轮 = 10 次 double-round(列轮 + 对角轮)
1952 for (int i = 0; i < 10; ++i)
1953 {
1954 // 列轮 QR 顺序:(0,4,8,12) (1,5,9,13) (2,6,10,14) (3,7,11,15)
1955 detail::ChaCha20QuarterRound(working[0], working[4], working[8], working[12]);
1956 detail::ChaCha20QuarterRound(working[1], working[5], working[9], working[13]);
1957 detail::ChaCha20QuarterRound(working[2], working[6], working[10], working[14]);
1958 detail::ChaCha20QuarterRound(working[3], working[7], working[11], working[15]);
1959 // 对角轮 QR 顺序:(0,5,10,15) (1,6,11,12) (2,7,8,13) (3,4,9,14)
1960 detail::ChaCha20QuarterRound(working[0], working[5], working[10], working[15]);
1961 detail::ChaCha20QuarterRound(working[1], working[6], working[11], working[12]);
1962 detail::ChaCha20QuarterRound(working[2], working[7], working[8], working[13]);
1963 detail::ChaCha20QuarterRound(working[3], working[4], working[9], working[14]);
1964 }
1965
1966 // 加初始状态后按小端序输出 64 字节到 m_buffer
1967 for (int i = 0; i < 16; ++i)
1968 {
1969 const std::uint32_t v = working[i] + state[i];
1970 m_buffer[i * 4 + 0] = static_cast<std::uint8_t>(v);
1971 m_buffer[i * 4 + 1] = static_cast<std::uint8_t>(v >> 8);
1972 m_buffer[i * 4 + 2] = static_cast<std::uint8_t>(v >> 16);
1973 m_buffer[i * 4 + 3] = static_cast<std::uint8_t>(v >> 24);
1974 }
1975
1976 if (m_state[8] == 0xFFFFFFFFU)
1977 {
1978 throw std::overflow_error("ChaCha20: 32-bit block counter overflow");
1979 }
1980 ++m_state[8]; // 递增 counter(2^20 字节阈值远早于 2^32 回绕,自动 reseed 防止复用)
1981 m_bufferPos = 0;
1982 }
1983
1984 // 自上次 reseed 以来输出字节数达到阈值时自动 reseed(前向安全)
1985 inline void ChaCha20::reseedIfNecessary()
1986 {
1987 if (m_bytesSinceReseed >= detail::ChaCha20ReseedThreshold)
1988 reseed();
1989 }
1990
1991 // 从 OS 熵重新播种:32 字节新 key + 12 字节新 nonce,重置 counter=0、缓存标记耗尽
1992 inline void ChaCha20::reseed()
1993 {
1994 std::array<std::uint8_t, 44> seed; // 32(key) + 12(nonce)
1995 SecureRandomBytes(seed.data(), seed.size());
1996 // key → m_state[0..7](小端序)
1997 for (int i = 0; i < 8; ++i)
1998 {
1999 m_state[i] = static_cast<std::uint32_t>(seed[i * 4])
2000 | (static_cast<std::uint32_t>(seed[i * 4 + 1]) << 8)
2001 | (static_cast<std::uint32_t>(seed[i * 4 + 2]) << 16)
2002 | (static_cast<std::uint32_t>(seed[i * 4 + 3]) << 24);
2003 }
2004 // nonce → m_state[9..11](小端序)
2005 for (int i = 0; i < 3; ++i)
2006 {
2007 m_state[9 + i] = static_cast<std::uint32_t>(seed[32 + i * 4])
2008 | (static_cast<std::uint32_t>(seed[32 + i * 4 + 1]) << 8)
2009 | (static_cast<std::uint32_t>(seed[32 + i * 4 + 2]) << 16)
2010 | (static_cast<std::uint32_t>(seed[32 + i * 4 + 3]) << 24);
2011 }
2012 m_state[8] = 0; // counter 重置
2013 m_bufferPos = 64; // 强制下次 operator() 触发新 block
2014 m_bytesSinceReseed = 0;
2015 detail::SecureWipe(seed.data(), seed.size()); // 擦除栈上密钥材料
2016 detail::SecureWipe(m_buffer.data(), m_buffer.size()); // 擦除旧 keystream
2017 }
2018
2019 // 生成一个 64-bit 随机数(从缓存取 8 字节,缓存耗尽时生成新 block)
2020 inline ChaCha20::result_type ChaCha20::operator()()
2021 {
2022 reseedIfNecessary();
2023 if (m_bufferPos == 64)
2024 generateBlock();
2025 // 从缓存取 8 字节,小端序组装为 uint64_t
2026 std::uint64_t result = 0;
2027 for (int i = 0; i < 8; ++i)
2028 result |= static_cast<std::uint64_t>(m_buffer[m_bufferPos + i]) << (8 * i);
2029 m_bufferPos += 8;
2030 m_bytesSinceReseed += 8;
2031 return result;
2032 }
2033
2034 inline void ChaCha20::discard(const unsigned long long n)
2035 {
2036 for (unsigned long long i = 0; i < n; ++i) operator()();
2037 }
2038
2039 // 重置默认引擎的种子(用于测试复现)
2040 inline void Reseed(std::uint64_t seed)
2041 {
2042 DefaultEngine() = Xoshiro256StarStar{ seed };
2043 }
2044
2045 // 重置为真随机种子
2046 inline void ReseedRandom()
2047 {
2048 DefaultEngine() = Xoshiro256StarStar{ RandomSeed() };
2049 }
2050
2053
2058 template <class T = int, std::enable_if_t<std::is_integral_v<T>>* = nullptr>
2059 [[nodiscard]]
2060 inline T RandInt(T min, T max)
2061 {
2062 assert(min <= max);
2063 std::uniform_int_distribution<T> dist(min, max);
2064 return dist(DefaultEngine());
2065 }
2066
2070 template <class T = int, std::enable_if_t<std::is_integral_v<T>>* = nullptr>
2071 [[nodiscard]]
2072 inline T RandInt(T max)
2073 {
2074 assert(max >= T{0});
2075 return RandInt<T>(T{0}, max);
2076 }
2077
2082 template <class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
2083 [[nodiscard]]
2084 inline T RandReal(T min = T{0}, T max = T{1})
2085 {
2086 assert(std::isfinite(min) && std::isfinite(max) && min <= max);
2087 std::uniform_real_distribution<T> dist(min, max);
2088 return dist(DefaultEngine());
2089 }
2090
2094 [[nodiscard]]
2095 inline bool RandBool(double p = 0.5)
2096 {
2097 assert(std::isfinite(p) && p >= 0.0 && p <= 1.0);
2098 std::bernoulli_distribution dist(p);
2099 return dist(DefaultEngine());
2100 }
2101
2106 template <class Engine>
2107 [[nodiscard]]
2108 inline bool RandBool(Engine& engine, double p = 0.5)
2109 {
2110 assert(std::isfinite(p) && p >= 0.0 && p <= 1.0);
2111 std::bernoulli_distribution dist(p);
2112 return dist(engine);
2113 }
2114
2118 [[nodiscard]]
2119 inline bool RandBernoulli(double p = 0.5)
2120 {
2121 assert(p >= 0.0 && p <= 1.0);
2122 return RandBool(p);
2123 }
2124
2129 template <class Engine>
2130 [[nodiscard]]
2131 inline bool RandBernoulli(Engine& engine, double p = 0.5)
2132 {
2133 assert(p >= 0.0 && p <= 1.0);
2134 return RandBool(engine, p);
2135 }
2136
2142 template <class CharT,
2143 std::enable_if_t<detail::is_character_v<CharT>>* = nullptr>
2144 [[nodiscard]]
2145 inline CharT RandChar(CharT min, CharT max)
2146 {
2147 assert(min <= max);
2148 using IntT = std::int64_t;
2149 std::uniform_int_distribution<IntT> dist(
2150 static_cast<IntT>(min), static_cast<IntT>(max));
2151 return static_cast<CharT>(dist(DefaultEngine()));
2152 }
2153
2157 template <class CharT,
2158 std::enable_if_t<detail::is_character_v<CharT>>* = nullptr>
2159 [[nodiscard]]
2160 inline CharT RandChar(CharT max)
2161 {
2162 return RandChar<CharT>(CharT{}, max);
2163 }
2164
2170 template <class CharT, class Engine,
2171 std::enable_if_t<detail::is_character_v<CharT>>* = nullptr>
2172 [[nodiscard]]
2173 inline CharT RandChar(Engine& engine, CharT min, CharT max)
2174 {
2175 assert(min <= max);
2176 using IntT = std::int64_t;
2177 std::uniform_int_distribution<IntT> dist(
2178 static_cast<IntT>(min), static_cast<IntT>(max));
2179 return static_cast<CharT>(dist(engine));
2180 }
2181
2186 template <class CharT, class Engine,
2187 std::enable_if_t<detail::is_character_v<CharT>>* = nullptr>
2188 [[nodiscard]]
2189 inline CharT RandChar(Engine& engine, CharT max)
2190 {
2191 return RandChar<CharT>(engine, CharT{}, max);
2192 }
2193
2195 //
2196 // RandChar / RandString 预设字符集(v1.2 新增)
2197 //
2198 // 提供常用字符集枚举,避免手写 ASCII 范围或字符串。
2199 //
2200
2201 // 预设字符集枚举
2202 enum class CharSet
2203 {
2204 Alphanumeric, // [A-Za-z0-9] 62 个
2205 Alpha, // [A-Za-z] 52 个
2206 Lower, // [a-z] 26 个
2207 Upper, // [A-Z] 26 个
2208 Digit, // [0-9] 10 个
2209 Hex, // [0-9a-f] 16 个
2210 Printable, // [!-~] 94 个可打印 ASCII
2211 Base64, // [A-Za-z0-9+/] 64 个(RFC 4648 §4 标准变体)
2212 Base64UrlSafe, // [A-Za-z0-9-_] 64 个(RFC 4648 §5 URL-safe 变体)
2213 };
2214
2215 namespace detail
2216 {
2217 // RandSample 分支选择阈值:n·K < size 时用 hash-set(实测交叉点 n≈N/127,K=64 留 2× 裕度)
2218 inline constexpr std::uint64_t HashSetThresholdK = 64;
2219
2220 // 返回预设字符集的字符串视图(零拷贝,指向静态存储)
2221 [[nodiscard]]
2222 inline std::string_view CharSetString(CharSet cs) noexcept
2223 {
2224 switch (cs)
2225 {
2226 case CharSet::Alphanumeric:
2227 return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
2228 case CharSet::Alpha:
2229 return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
2230 case CharSet::Lower:
2231 return "abcdefghijklmnopqrstuvwxyz";
2232 case CharSet::Upper:
2233 return "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
2234 case CharSet::Digit:
2235 return "0123456789";
2236 case CharSet::Hex:
2237 return "0123456789abcdef";
2238 case CharSet::Printable:
2239 return "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
2240 case CharSet::Base64:
2241 return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2242 case CharSet::Base64UrlSafe:
2243 return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
2244 }
2245 return "";
2246 }
2247 }
2248
2253 [[nodiscard]]
2254 inline char RandChar(CharSet cs)
2255 {
2256 const auto charset = detail::CharSetString(cs);
2257 if (charset.empty())
2258 throw std::invalid_argument("RandChar: charset is empty");
2259 auto& rng = DefaultEngine();
2260 std::uniform_int_distribution<std::size_t> dist(0, charset.size() - 1);
2261 return charset[dist(rng)];
2262 }
2263
2268 template <class Engine>
2269 [[nodiscard]]
2270 inline char RandChar(Engine& engine, CharSet cs)
2271 {
2272 const auto charset = detail::CharSetString(cs);
2273 if (charset.empty())
2274 throw std::invalid_argument("RandChar: charset is empty");
2275 std::uniform_int_distribution<std::size_t> dist(0, charset.size() - 1);
2276 return charset[dist(engine)];
2277 }
2278
2281
2286 template <class Container,
2287 std::enable_if_t<detail::is_random_access_container_v<Container>>* = nullptr>
2288 [[nodiscard]]
2289 inline decltype(auto) RandElement(Container& c)
2290 {
2291 if (std::empty(c))
2292 throw std::invalid_argument("RandElement: empty container");
2293 return c[RandInt<std::size_t>(static_cast<std::size_t>(std::size(c) - 1))];
2294 }
2295
2300 template <class Container,
2301 std::enable_if_t<detail::is_random_access_container_v<std::decay_t<Container>>>* = nullptr>
2302 [[nodiscard]]
2303 inline typename std::decay_t<Container>::value_type RandElement(Container&& c)
2304 {
2305 if (std::empty(c))
2306 throw std::invalid_argument("RandElement: empty container");
2307 return c[RandInt<std::size_t>(static_cast<std::size_t>(std::size(c) - 1))];
2308 }
2309
2315 template <class It,
2316 std::enable_if_t<detail::is_random_access_iterator_v<It>>* = nullptr>
2317 [[nodiscard]]
2318 inline It RandElement(It first, It last)
2319 {
2320 using Diff = typename std::iterator_traits<It>::difference_type;
2321 const Diff n = std::distance(first, last);
2322 if (n <= 0)
2323 throw std::invalid_argument("RandElement: empty range");
2324 return std::next(first, RandInt<Diff>(Diff{0}, n - 1));
2325 }
2326
2332 template <class It,
2333 std::enable_if_t<detail::is_input_iterator_v<It>
2334 && !detail::is_random_access_iterator_v<It>>* = nullptr>
2335 [[nodiscard]]
2336 inline It RandElement(It first, It last)
2337 {
2338 if (first == last)
2339 throw std::invalid_argument("RandElement: empty range");
2340 It selected = first;
2341 ++first;
2342 for (typename std::iterator_traits<It>::difference_type i = 1;
2343 first != last; ++first, ++i)
2344 {
2345 if (RandInt<typename std::iterator_traits<It>::difference_type>(0, i) == 0)
2346 selected = first;
2347 }
2348 return selected;
2349 }
2350
2356 template <class It, class Engine,
2357 std::enable_if_t<detail::is_random_access_iterator_v<It>>* = nullptr>
2358 [[nodiscard]]
2359 inline It RandElement(Engine& engine, It first, It last)
2360 {
2361 using Diff = typename std::iterator_traits<It>::difference_type;
2362 const Diff n = std::distance(first, last);
2363 if (n <= 0)
2364 throw std::invalid_argument("RandElement: empty range");
2365 return std::next(first, RandInt<Diff>(engine, Diff{0}, n - 1));
2366 }
2367
2373 template <class It, class Engine,
2374 std::enable_if_t<detail::is_input_iterator_v<It>
2375 && !detail::is_random_access_iterator_v<It>>* = nullptr>
2376 [[nodiscard]]
2377 inline It RandElement(Engine& engine, It first, It last)
2378 {
2379 if (first == last)
2380 throw std::invalid_argument("RandElement: empty range");
2381 It selected = first;
2382 ++first;
2383 for (typename std::iterator_traits<It>::difference_type i = 1;
2384 first != last; ++first, ++i)
2385 {
2386 if (RandInt<typename std::iterator_traits<It>::difference_type>(
2387 engine, typename std::iterator_traits<It>::difference_type{0}, i) == 0)
2388 selected = first;
2389 }
2390 return selected;
2391 }
2392
2393
2396
2401 template <class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
2402 [[nodiscard]]
2403 inline T RandNormal(T mean = T{0}, T stddev = T{1})
2404 {
2405 assert(std::isfinite(mean) && std::isfinite(stddev) && stddev > T{0});
2406 std::normal_distribution<T> dist(mean, stddev);
2407 return dist(DefaultEngine());
2408 }
2409
2415 template <class Engine, class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
2416 [[nodiscard]]
2417 inline T RandNormal(Engine& engine, T mean = T{0}, T stddev = T{1})
2418 {
2419 assert(std::isfinite(mean) && std::isfinite(stddev) && stddev > T{0});
2420 std::normal_distribution<T> dist(mean, stddev);
2421 return dist(engine);
2422 }
2423
2426 template <class Container,
2427 std::enable_if_t<detail::is_random_access_container_v<Container>>* = nullptr>
2428 inline void RandShuffle(Container&& c)
2429 {
2430 std::shuffle(c.begin(), c.end(), DefaultEngine());
2431 }
2432
2440 template <class It, class T,
2441 std::enable_if_t<detail::is_rand_fillable_v<It, T>>* = nullptr>
2442 inline void RandFill(It first, It last, T min, T max)
2443 {
2444 assert(min <= max);
2445 auto& rng = DefaultEngine();
2446 if constexpr (std::is_integral_v<T>)
2447 {
2448 std::uniform_int_distribution<T> dist(min, max);
2449 for (; first != last; ++first) *first = dist(rng);
2450 }
2451 else
2452 {
2453 std::uniform_real_distribution<T> dist(min, max);
2454 for (; first != last; ++first) *first = dist(rng);
2455 }
2456 }
2457
2464 template <class It, class T, class Engine,
2465 std::enable_if_t<detail::is_rand_fillable_v<It, T>>* = nullptr>
2466 inline void RandFill(Engine& engine, It first, It last, T min, T max)
2467 {
2468 assert(min <= max);
2469 if constexpr (std::is_integral_v<T>)
2470 {
2471 std::uniform_int_distribution<T> dist(min, max);
2472 for (; first != last; ++first) *first = dist(engine);
2473 }
2474 else
2475 {
2476 std::uniform_real_distribution<T> dist(min, max);
2477 for (; first != last; ++first) *first = dist(engine);
2478 }
2479 }
2480
2486 template <class T,
2487 std::enable_if_t<std::is_integral_v<T>>* = nullptr>
2488 [[nodiscard]]
2489 inline std::vector<T> RandVector(T min, T max, std::size_t n)
2490 {
2491 assert(min <= max);
2492 std::vector<T> v;
2493 v.reserve(n);
2494 auto& rng = DefaultEngine();
2495 std::uniform_int_distribution<T> dist(min, max);
2496 for (std::size_t i = 0; i < n; ++i)
2497 v.push_back(dist(rng));
2498 return v;
2499 }
2500
2506 template <class T,
2507 std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
2508 [[nodiscard]]
2509 inline std::vector<T> RandVector(T min, T max, std::size_t n)
2510 {
2511 assert(min <= max);
2512 std::vector<T> v;
2513 v.reserve(n);
2514 auto& rng = DefaultEngine();
2515 std::uniform_real_distribution<T> dist(min, max);
2516 for (std::size_t i = 0; i < n; ++i)
2517 v.push_back(dist(rng));
2518 return v;
2519 }
2520
2527 template <class T, class Engine,
2528 std::enable_if_t<std::is_integral_v<T>>* = nullptr>
2529 [[nodiscard]]
2530 inline std::vector<T> RandVector(Engine& engine, T min, T max, std::size_t n)
2531 {
2532 assert(min <= max);
2533 std::vector<T> v;
2534 v.reserve(n);
2535 std::uniform_int_distribution<T> dist(min, max);
2536 for (std::size_t i = 0; i < n; ++i)
2537 v.push_back(dist(engine));
2538 return v;
2539 }
2540
2547 template <class T, class Engine,
2548 std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
2549 [[nodiscard]]
2550 inline std::vector<T> RandVector(Engine& engine, T min, T max, std::size_t n)
2551 {
2552 assert(min <= max);
2553 std::vector<T> v;
2554 v.reserve(n);
2555 std::uniform_real_distribution<T> dist(min, max);
2556 for (std::size_t i = 0; i < n; ++i)
2557 v.push_back(dist(engine));
2558 return v;
2559 }
2560
2564 template <class WeightContainer>
2565 [[nodiscard]]
2566 inline typename WeightContainer::size_type RandWeighted(const WeightContainer& weights)
2567 {
2568 assert(!weights.empty() && std::all_of(weights.begin(), weights.end(), [](auto w) { return w >= 0; }) && std::any_of(weights.begin(), weights.end(), [](auto w) { return w > 0; }));
2569 using Size = typename WeightContainer::size_type;
2570 std::discrete_distribution<Size> dist(weights.begin(), weights.end());
2571 return dist(DefaultEngine());
2572 }
2573
2578 template <class Engine, class WeightContainer>
2579 [[nodiscard]]
2580 inline typename WeightContainer::size_type RandWeighted(Engine& engine, const WeightContainer& weights)
2581 {
2582 assert(!weights.empty() && std::all_of(weights.begin(), weights.end(), [](auto w) { return w >= 0; }) && std::any_of(weights.begin(), weights.end(), [](auto w) { return w > 0; }));
2583 using Size = typename WeightContainer::size_type;
2584 std::discrete_distribution<Size> dist(weights.begin(), weights.end());
2585 return dist(engine);
2586 }
2587
2591 template <class IntType>
2592 [[nodiscard]]
2593 inline IntType RandWeighted(std::discrete_distribution<IntType>& dist)
2594 {
2595 return dist(DefaultEngine());
2596 }
2597
2602 template <class Engine, class IntType>
2603 [[nodiscard]]
2604 inline IntType RandWeighted(Engine& engine, std::discrete_distribution<IntType>& dist)
2605 {
2606 return dist(engine);
2607 }
2608
2614 template <class T, class Engine, std::enable_if_t<std::is_integral_v<T>>* = nullptr>
2615 [[nodiscard]]
2616 inline T RandInt(Engine& engine, T min, T max)
2617 {
2618 assert(min <= max);
2619 std::uniform_int_distribution<T> dist(min, max);
2620 return dist(engine);
2621 }
2622
2628 template <class T, class Engine, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
2629 [[nodiscard]]
2630 inline T RandReal(Engine& engine, T min = T{0}, T max = T{1})
2631 {
2632 assert(std::isfinite(min) && std::isfinite(max) && min <= max);
2633 std::uniform_real_distribution<T> dist(min, max);
2634 return dist(engine);
2635 }
2636
2638 //
2639 // 扩展便捷 API
2640 //
2641
2646 template <class Container,
2647 std::enable_if_t<detail::is_random_access_container_v<Container>>* = nullptr>
2648 [[nodiscard]]
2649 inline auto RandSample(const Container& c, typename Container::size_type n)
2650 {
2651 using T = typename Container::value_type;
2652 using Size = typename Container::size_type;
2653 std::vector<T> pool(c.begin(), c.end());
2654 const Size size = static_cast<Size>(pool.size());
2655 if (n >= size) return pool;
2656 auto& rng = DefaultEngine();
2657 for (Size i = 0; i < n; ++i)
2658 {
2659 std::uniform_int_distribution<Size> dist(i, size - 1);
2660 const Size j = dist(rng);
2661 auto tmp = std::move(pool[i]);
2662 pool[i] = std::move(pool[j]);
2663 pool[j] = std::move(tmp);
2664 }
2665 pool.resize(n);
2666 return pool;
2667 }
2668
2669 // ============================================================
2670 // RandSample 迭代器版(v1.2 新增)
2671 // 路径 1:随机访问迭代器 —— hash-set / 索引数组双分支
2672 // 路径 2:输入迭代器 —— reservoir sampling (Algorithm R, i+1 修复)
2673 // ============================================================
2674
2675 // 路径 1:随机访问迭代器(hash-set / 索引数组双分支)
2676 template <class It,
2677 std::enable_if_t<detail::is_random_access_iterator_v<It>>* = nullptr>
2678 [[nodiscard]]
2679 inline std::vector<typename std::iterator_traits<It>::value_type>
2680 RandSample(It first, It last, typename std::iterator_traits<It>::difference_type n)
2681 {
2682 using Diff = typename std::iterator_traits<It>::difference_type;
2683 using T = typename std::iterator_traits<It>::value_type;
2684 const Diff size = std::distance(first, last);
2685 if (n <= 0 || size == 0)
2686 return {};
2687 if (n >= size)
2688 return std::vector<T>(first, last);
2689
2690 auto& rng = DefaultEngine();
2691
2692 // 分支选择:n·K < size 时 hash-set 内存优(O(n));否则索引数组常数优(O(N))
2693 const auto sizeU = static_cast<std::uint64_t>(size);
2694 // 线性阈值:n·K < size 时用 hash-set(实测交叉点 n≈N/127,K=64 留 2× 裕度)
2695 if (static_cast<std::uint64_t>(n) * detail::HashSetThresholdK < sizeU)
2696 {
2697 // hash-set 分支:O(n) 内存,O(n) 期望时间
2698 std::unordered_set<Diff> selected;
2699 selected.reserve(static_cast<std::size_t>(n));
2700 std::vector<T> result;
2701 result.reserve(static_cast<std::size_t>(n));
2702 while (result.size() < static_cast<std::size_t>(n))
2703 {
2704 std::uniform_int_distribution<Diff> dist(Diff{0}, static_cast<Diff>(sizeU - 1));
2705 const Diff idx = dist(rng);
2706 if (selected.insert(idx).second)
2707 result.push_back(first[idx]);
2708 }
2709 return result;
2710 }
2711
2712 // 索引数组分支:O(N) 内存,O(N) 时间,无碰撞
2713 std::vector<Diff> indices(static_cast<std::size_t>(size));
2714 for (Diff i = 0; i < size; ++i)
2715 indices[static_cast<std::size_t>(i)] = i;
2716
2717 // Fisher-Yates 前 n 步:j ∈ [i, size-1]
2718 for (Diff i = 0; i < n; ++i)
2719 {
2720 std::uniform_int_distribution<Diff> dist(i, static_cast<Diff>(size - 1));
2721 const Diff j = dist(rng);
2722 std::swap(indices[static_cast<std::size_t>(i)],
2723 indices[static_cast<std::size_t>(j)]);
2724 }
2725
2726 std::vector<T> result;
2727 result.reserve(static_cast<std::size_t>(n));
2728 for (Diff i = 0; i < n; ++i)
2729 result.push_back(first[indices[static_cast<std::size_t>(i)]]);
2730 return result;
2731 }
2732
2733 // 路径 2:输入迭代器(reservoir sampling, Algorithm R, i+1 修复)
2734 template <class It,
2735 std::enable_if_t<detail::is_input_iterator_v<It>
2736 && !detail::is_random_access_iterator_v<It>>* = nullptr>
2737 [[nodiscard]]
2738 inline std::vector<typename std::iterator_traits<It>::value_type>
2739 RandSample(It first, It last, typename std::iterator_traits<It>::difference_type n)
2740 {
2741 using Diff = typename std::iterator_traits<It>::difference_type;
2742 using T = typename std::iterator_traits<It>::value_type;
2743 if (n <= 0)
2744 return {};
2745
2746 std::vector<T> reservoir;
2747 reservoir.reserve(static_cast<std::size_t>(n));
2748
2749 // 填满蓄水池
2750 Diff i = 0;
2751 for (; i < n && first != last; ++i, ++first)
2752 reservoir.push_back(*first);
2753
2754 if (first == last)
2755 return reservoir; // 元素不足 n,返回全部
2756
2757 // Algorithm R:第 i 个元素(i >= n,0-indexed)以 n/(i+1) 概率替换蓄水池随机位置
2758 // 关键:j ∈ [0, i](闭区间),uniform_int_distribution(0, i) 正好是 [0, i] 闭区间
2759 auto& rng = DefaultEngine();
2760 for (; first != last; ++i, ++first)
2761 {
2762 std::uniform_int_distribution<Diff> dist(Diff{0}, i);
2763 const Diff j = dist(rng);
2764 if (j < n)
2765 reservoir[static_cast<std::size_t>(j)] = *first;
2766 }
2767 return reservoir;
2768 }
2769
2770 // 引擎重载 —— 随机访问迭代器
2771 template <class It, class Engine,
2772 std::enable_if_t<detail::is_random_access_iterator_v<It>>* = nullptr>
2773 [[nodiscard]]
2774 inline std::vector<typename std::iterator_traits<It>::value_type>
2775 RandSample(Engine& engine, It first, It last, typename std::iterator_traits<It>::difference_type n)
2776 {
2777 using Diff = typename std::iterator_traits<It>::difference_type;
2778 using T = typename std::iterator_traits<It>::value_type;
2779 const Diff size = std::distance(first, last);
2780 if (n <= 0 || size == 0)
2781 return {};
2782 if (n >= size)
2783 return std::vector<T>(first, last);
2784
2785 const auto sizeU = static_cast<std::uint64_t>(size);
2786 // 线性阈值:n·K < size 时用 hash-set(实测交叉点 n≈N/127,K=64 留 2× 裕度)
2787 if (static_cast<std::uint64_t>(n) * detail::HashSetThresholdK < sizeU)
2788 {
2789 std::unordered_set<Diff> selected;
2790 selected.reserve(static_cast<std::size_t>(n));
2791 std::vector<T> result;
2792 result.reserve(static_cast<std::size_t>(n));
2793 while (result.size() < static_cast<std::size_t>(n))
2794 {
2795 std::uniform_int_distribution<Diff> dist(Diff{0}, static_cast<Diff>(sizeU - 1));
2796 const Diff idx = dist(engine);
2797 if (selected.insert(idx).second)
2798 result.push_back(first[idx]);
2799 }
2800 return result;
2801 }
2802
2803 std::vector<Diff> indices(static_cast<std::size_t>(size));
2804 for (Diff i = 0; i < size; ++i)
2805 indices[static_cast<std::size_t>(i)] = i;
2806
2807 for (Diff i = 0; i < n; ++i)
2808 {
2809 std::uniform_int_distribution<Diff> dist(i, static_cast<Diff>(size - 1));
2810 const Diff j = dist(engine);
2811 std::swap(indices[static_cast<std::size_t>(i)],
2812 indices[static_cast<std::size_t>(j)]);
2813 }
2814
2815 std::vector<T> result;
2816 result.reserve(static_cast<std::size_t>(n));
2817 for (Diff i = 0; i < n; ++i)
2818 result.push_back(first[indices[static_cast<std::size_t>(i)]]);
2819 return result;
2820 }
2821
2822 // 引擎重载 —— 输入迭代器(reservoir)
2823 template <class It, class Engine,
2824 std::enable_if_t<detail::is_input_iterator_v<It>
2825 && !detail::is_random_access_iterator_v<It>>* = nullptr>
2826 [[nodiscard]]
2827 inline std::vector<typename std::iterator_traits<It>::value_type>
2828 RandSample(Engine& engine, It first, It last, typename std::iterator_traits<It>::difference_type n)
2829 {
2830 using Diff = typename std::iterator_traits<It>::difference_type;
2831 using T = typename std::iterator_traits<It>::value_type;
2832 if (n <= 0)
2833 return {};
2834
2835 std::vector<T> reservoir;
2836 reservoir.reserve(static_cast<std::size_t>(n));
2837
2838 Diff i = 0;
2839 for (; i < n && first != last; ++i, ++first)
2840 reservoir.push_back(*first);
2841
2842 if (first == last)
2843 return reservoir;
2844
2845 // Algorithm R:j ∈ [0, i] 闭区间
2846 for (; first != last; ++i, ++first)
2847 {
2848 std::uniform_int_distribution<Diff> dist(Diff{0}, i);
2849 const Diff j = dist(engine);
2850 if (j < n)
2851 reservoir[static_cast<std::size_t>(j)] = *first;
2852 }
2853 return reservoir;
2854 }
2855
2859 [[nodiscard]]
2860 inline std::vector<std::size_t> RandPermutation(std::size_t n)
2861 {
2862 std::vector<std::size_t> perm(n);
2863 for (std::size_t i = 0; i < n; ++i) perm[i] = i;
2864 if (n < 2) return perm;
2865 auto& rng = DefaultEngine();
2866 for (std::size_t i = n - 1; i > 0; --i)
2867 {
2868 std::uniform_int_distribution<std::size_t> dist(0, i);
2869 const std::size_t j = dist(rng);
2870 auto tmp = perm[i];
2871 perm[i] = perm[j];
2872 perm[j] = tmp;
2873 }
2874 return perm;
2875 }
2876
2879
2885 [[nodiscard]]
2886 inline std::string RandString(std::size_t length, std::string_view charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
2887 {
2888 if (charset.empty())
2889 throw std::invalid_argument("RandString: charset is empty");
2890 std::string result(length, '\0');
2891 auto& rng = DefaultEngine();
2892 std::uniform_int_distribution<std::size_t> dist(0, charset.size() - 1);
2893 for (std::size_t i = 0; i < length; ++i)
2894 result[i] = charset[dist(rng)];
2895 return result;
2896 }
2897
2902 [[nodiscard]]
2903 inline std::string RandString(std::size_t n, CharSet cs)
2904 {
2905 return RandString(n, detail::CharSetString(cs));
2906 }
2907
2913 template <class Engine>
2914 [[nodiscard]]
2915 inline std::string RandString(Engine& engine, std::size_t n, CharSet cs)
2916 {
2917 const auto charset = detail::CharSetString(cs);
2918 if (charset.empty())
2919 throw std::invalid_argument("RandString: charset is empty");
2920 std::string result(n, '\0');
2921 std::uniform_int_distribution<std::size_t> dist(0, charset.size() - 1);
2922 for (std::size_t i = 0; i < n; ++i)
2923 result[i] = charset[dist(engine)];
2924 return result;
2925 }
2926
2930 template <class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
2931 [[nodiscard]]
2932 inline T RandExp(T lambda = T{1})
2933 {
2934 assert(std::isfinite(lambda) && lambda > T{0});
2935 std::exponential_distribution<T> dist(lambda);
2936 return dist(DefaultEngine());
2937 }
2938
2943 template <class Engine, class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
2944 [[nodiscard]]
2945 inline T RandExp(Engine& engine, T lambda = T{1})
2946 {
2947 assert(std::isfinite(lambda) && lambda > T{0});
2948 std::exponential_distribution<T> dist(lambda);
2949 return dist(engine);
2950 }
2951
2955 template <class T = int, std::enable_if_t<std::is_integral_v<T>>* = nullptr>
2956 [[nodiscard]]
2957 inline T RandPoisson(double mean = 1.0)
2958 {
2959 assert(std::isfinite(mean) && mean >= 0.0);
2960 if (mean == 0.0) return T{0};
2961 std::poisson_distribution<T> dist(mean);
2962 return dist(DefaultEngine());
2963 }
2964
2969 template <class Engine, class T = int, std::enable_if_t<std::is_integral_v<T>>* = nullptr>
2970 [[nodiscard]]
2971 inline T RandPoisson(Engine& engine, double mean = 1.0)
2972 {
2973 assert(std::isfinite(mean) && mean >= 0.0);
2974 if (mean == 0.0) return T{0};
2975 std::poisson_distribution<T> dist(mean);
2976 return dist(engine);
2977 }
2978
2983 template <class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
2984 [[nodiscard]]
2985 inline T RandGamma(T alpha = T{1}, T beta = T{1})
2986 {
2987 assert(std::isfinite(alpha) && std::isfinite(beta) && alpha > T{0} && beta > T{0});
2988 std::gamma_distribution<T> dist(alpha, beta);
2989 return dist(DefaultEngine());
2990 }
2991
2997 template <class Engine, class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
2998 [[nodiscard]]
2999 inline T RandGamma(Engine& engine, T alpha = T{1}, T beta = T{1})
3000 {
3001 assert(std::isfinite(alpha) && std::isfinite(beta) && alpha > T{0} && beta > T{0});
3002 std::gamma_distribution<T> dist(alpha, beta);
3003 return dist(engine);
3004 }
3005
3010 template <class T = int, std::enable_if_t<std::is_integral_v<T>>* = nullptr>
3011 [[nodiscard]]
3012 inline T RandBinomial(T t = 1, double p = 0.5)
3013 {
3014 assert(t >= 0 && std::isfinite(p) && p >= 0.0 && p <= 1.0);
3015 std::binomial_distribution<T> dist(t, p);
3016 return dist(DefaultEngine());
3017 }
3018
3024 template <class T = int, class Engine, std::enable_if_t<std::is_integral_v<T>>* = nullptr>
3025 [[nodiscard]]
3026 inline T RandBinomial(Engine& engine, T t = 1, double p = 0.5)
3027 {
3028 assert(t >= 0 && std::isfinite(p) && p >= 0.0 && p <= 1.0);
3029 std::binomial_distribution<T> dist(t, p);
3030 return dist(engine);
3031 }
3032
3037 template <class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
3038 [[nodiscard]]
3039 inline T RandLogNormal(T mean = T{0}, T stddev = T{1})
3040 {
3041 assert(std::isfinite(mean) && std::isfinite(stddev) && stddev > T{0});
3042 std::lognormal_distribution<T> dist(mean, stddev);
3043 return dist(DefaultEngine());
3044 }
3045
3051 template <class T = double, class Engine, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
3052 [[nodiscard]]
3053 inline T RandLogNormal(Engine& engine, T mean = T{0}, T stddev = T{1})
3054 {
3055 assert(std::isfinite(mean) && std::isfinite(stddev) && stddev > T{0});
3056 std::lognormal_distribution<T> dist(mean, stddev);
3057 return dist(engine);
3058 }
3059
3063 template <class T = int, std::enable_if_t<std::is_integral_v<T>>* = nullptr>
3064 [[nodiscard]]
3065 inline T RandGeometric(double p = 0.5)
3066 {
3067 assert(p > 0.0 && p <= 1.0);
3068 std::geometric_distribution<T> dist(p);
3069 return dist(DefaultEngine());
3070 }
3071
3076 template <class T = int, class Engine, std::enable_if_t<std::is_integral_v<T>>* = nullptr>
3077 [[nodiscard]]
3078 inline T RandGeometric(Engine& engine, double p = 0.5)
3079 {
3080 assert(p > 0.0 && p <= 1.0);
3081 std::geometric_distribution<T> dist(p);
3082 return dist(engine);
3083 }
3084
3089 template <class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
3090 [[nodiscard]]
3091 inline T RandCauchy(T a = T{0}, T b = T{1})
3092 {
3093 assert(std::isfinite(a) && std::isfinite(b) && b > T{0});
3094 std::cauchy_distribution<T> dist(a, b);
3095 return dist(DefaultEngine());
3096 }
3097
3103 template <class T = double, class Engine, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
3104 [[nodiscard]]
3105 inline T RandCauchy(Engine& engine, T a = T{0}, T b = T{1})
3106 {
3107 assert(std::isfinite(a) && std::isfinite(b) && b > T{0});
3108 std::cauchy_distribution<T> dist(a, b);
3109 return dist(engine);
3110 }
3111
3116 template <class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
3117 [[nodiscard]]
3118 inline T RandWeibull(T a = T{1}, T b = T{1})
3119 {
3120 assert(std::isfinite(a) && std::isfinite(b) && a > T{0} && b > T{0});
3121 std::weibull_distribution<T> dist(a, b);
3122 return dist(DefaultEngine());
3123 }
3124
3130 template <class T = double, class Engine, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
3131 [[nodiscard]]
3132 inline T RandWeibull(Engine& engine, T a = T{1}, T b = T{1})
3133 {
3134 assert(std::isfinite(a) && std::isfinite(b) && a > T{0} && b > T{0});
3135 std::weibull_distribution<T> dist(a, b);
3136 return dist(engine);
3137 }
3138
3143 template <class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
3144 [[nodiscard]]
3145 inline T RandExtremeValue(T a = T{0}, T b = T{1})
3146 {
3147 assert(std::isfinite(a) && std::isfinite(b) && b > T{0});
3148 std::extreme_value_distribution<T> dist(a, b);
3149 return dist(DefaultEngine());
3150 }
3151
3157 template <class T = double, class Engine, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
3158 [[nodiscard]]
3159 inline T RandExtremeValue(Engine& engine, T a = T{0}, T b = T{1})
3160 {
3161 assert(std::isfinite(a) && std::isfinite(b) && b > T{0});
3162 std::extreme_value_distribution<T> dist(a, b);
3163 return dist(engine);
3164 }
3165
3169 template <class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
3170 [[nodiscard]]
3171 inline T RandChiSquared(T n = T{1})
3172 {
3173 assert(std::isfinite(n) && n > T{0});
3174 std::chi_squared_distribution<T> dist(n);
3175 return dist(DefaultEngine());
3176 }
3177
3182 template <class T = double, class Engine, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
3183 [[nodiscard]]
3184 inline T RandChiSquared(Engine& engine, T n = T{1})
3185 {
3186 assert(std::isfinite(n) && n > T{0});
3187 std::chi_squared_distribution<T> dist(n);
3188 return dist(engine);
3189 }
3190
3194 template <class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
3195 [[nodiscard]]
3196 inline T RandStudentT(T n = T{1})
3197 {
3198 assert(std::isfinite(n) && n > T{0});
3199 std::student_t_distribution<T> dist(n);
3200 return dist(DefaultEngine());
3201 }
3202
3207 template <class T = double, class Engine, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
3208 [[nodiscard]]
3209 inline T RandStudentT(Engine& engine, T n = T{1})
3210 {
3211 assert(std::isfinite(n) && n > T{0});
3212 std::student_t_distribution<T> dist(n);
3213 return dist(engine);
3214 }
3215
3220 template <class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
3221 [[nodiscard]]
3222 inline T RandFisherF(T m = T{1}, T n = T{1})
3223 {
3224 assert(std::isfinite(m) && std::isfinite(n) && m > T{0} && n > T{0});
3225 std::fisher_f_distribution<T> dist(m, n);
3226 return dist(DefaultEngine());
3227 }
3228
3234 template <class T = double, class Engine, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
3235 [[nodiscard]]
3236 inline T RandFisherF(Engine& engine, T m = T{1}, T n = T{1})
3237 {
3238 assert(std::isfinite(m) && std::isfinite(n) && m > T{0} && n > T{0});
3239 std::fisher_f_distribution<T> dist(m, n);
3240 return dist(engine);
3241 }
3242
3248 template <class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
3249 [[nodiscard]]
3250 inline T RandBeta(T a = T{1}, T b = T{1})
3251 {
3252 assert(std::isfinite(a) && std::isfinite(b) && a > T{0} && b > T{0});
3253 std::gamma_distribution<T> distA(a, T{1});
3254 std::gamma_distribution<T> distB(b, T{1});
3255 auto& rng = DefaultEngine();
3256 const T x = distA(rng);
3257 const T y = distB(rng);
3258 const T sum = x + y;
3259 if (sum == T{0})
3260 return RandBool(rng, static_cast<double>(a) / static_cast<double>(a + b)) ? T{1} : T{0};
3261 return x / sum;
3262 }
3263
3269 template <class T = double, class Engine, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
3270 [[nodiscard]]
3271 inline T RandBeta(Engine& engine, T a = T{1}, T b = T{1})
3272 {
3273 assert(std::isfinite(a) && std::isfinite(b) && a > T{0} && b > T{0});
3274 std::gamma_distribution<T> distA(a, T{1});
3275 std::gamma_distribution<T> distB(b, T{1});
3276 const T x = distA(engine);
3277 const T y = distB(engine);
3278 const T sum = x + y;
3279 if (sum == T{0})
3280 return RandBool(engine, static_cast<double>(a) / static_cast<double>(a + b)) ? T{1} : T{0};
3281 return x / sum;
3282 }
3283
3287 template <int N, class T = std::uint64_t, std::enable_if_t<std::is_integral_v<T> && (N > 0) && (N <= 64) && (N <= std::numeric_limits<T>::digits)>* = nullptr>
3288 [[nodiscard]]
3289 inline T RandBits() noexcept
3290 {
3291 auto& rng = DefaultEngine();
3292 if constexpr (N == 64)
3293 return static_cast<T>(rng());
3294 else
3295 return static_cast<T>(rng() & ((std::uint64_t{1} << N) - 1));
3296 }
3297
3302 template <class Engine>
3303 [[nodiscard]]
3304 inline std::string RandUUID(Engine& engine)
3305 {
3306 static constexpr char hex[] = "0123456789abcdef";
3307 std::string uuid(36, '-');
3308 const std::uint64_t u1 = detail::Generate64Bits(engine);
3309 const std::uint64_t u2 = detail::Generate64Bits(engine);
3310
3311 for (int i = 0; i < 8; ++i)
3312 uuid[i] = hex[(u1 >> (i * 4)) & 0xFU];
3313 for (int i = 0; i < 4; ++i)
3314 uuid[9 + i] = hex[(u1 >> ((8 + i) * 4)) & 0xFU];
3315 uuid[14] = '4';
3316 for (int i = 1; i < 4; ++i)
3317 uuid[14 + i] = hex[(u1 >> ((12 + i) * 4)) & 0xFU];
3318 uuid[19] = hex[8 + ((u2 >> 0) & 0x3U)];
3319 for (int i = 1; i < 4; ++i)
3320 uuid[19 + i] = hex[(u2 >> (i * 4)) & 0xFU];
3321 for (int i = 0; i < 12; ++i)
3322 uuid[24 + i] = hex[(u2 >> ((4 + i) * 4)) & 0xFU];
3323
3324 return uuid;
3325 }
3326
3327 [[nodiscard]]
3328 inline std::string RandUUID()
3329 {
3330 return RandUUID(DefaultEngine());
3331 }
3332
3334 //
3335 // 静态断言:确认引擎满足 UniformRandomBitGenerator 要求
3336 //
3337
3338 static_assert(std::is_same_v<SplitMix64::result_type, std::uint64_t>);
3339 static_assert(std::is_same_v<Xoshiro256StarStar::result_type, std::uint64_t>);
3340 static_assert(std::is_same_v<Xoroshiro128StarStar::result_type, std::uint64_t>);
3341 static_assert(std::is_same_v<Xoshiro128StarStar::result_type, std::uint32_t>);
3342 static_assert(std::is_same_v<Xoroshiro64StarStar::result_type, std::uint32_t>);
3343 static_assert(std::is_same_v<SFC64::result_type, std::uint64_t>);
3344 static_assert(std::is_same_v<RomuDuoJr::result_type, std::uint64_t>);
3345 static_assert(std::is_same_v<ChaCha20::result_type, std::uint64_t>);
3346 static_assert(SplitMix64::min() < SplitMix64::max());
3347 static_assert(Xoshiro256StarStar::min() < Xoshiro256StarStar::max());
3348 static_assert(Xoroshiro128StarStar::min() < Xoroshiro128StarStar::max());
3349 static_assert(Xoshiro128StarStar::min() < Xoshiro128StarStar::max());
3350 static_assert(Xoroshiro64StarStar::min() < Xoroshiro64StarStar::max());
3351 static_assert(SFC64::min() < SFC64::max());
3352 static_assert(RomuDuoJr::min() < RomuDuoJr::max());
3353 static_assert(ChaCha20::min() < ChaCha20::max());
3354
3355 // ========================================================================
3356 // 流式运算符 operator<< / operator>>
3357 // 仅对 state_type 为可索引容器类的引擎生效(is_serializable_engine_v)
3358 // SplitMix64(state_type = uint64_t 标量)不支持,由 is_indexable_state_v 排除
3359 // 格式兼容 std::random_engine:空格分隔的十进制数序列
3360 // ========================================================================
3361
3362 // 流式输出引擎状态
3363 template <class CharT, class Traits, class Engine,
3364 std::enable_if_t<detail::is_serializable_engine_v<Engine>>* = nullptr>
3365 std::basic_ostream<CharT, Traits>&
3366 operator<<(std::basic_ostream<CharT, Traits>& os, const Engine& engine)
3367 {
3368 auto state = engine.serialize();
3369 auto it = state.begin();
3370 if (it != state.end())
3371 {
3372 os << *it;
3373 for (++it; it != state.end(); ++it)
3374 os << os.widen(' ') << *it;
3375 }
3376 return os;
3377 }
3378
3379 // 流式恢复引擎状态
3380 // 若解析失败(读取不足或流错误),setstate(failbit) 且引擎状态保持不变
3381 // (与 std::random_engine 一致:先读取到临时 state,全部成功才 deserialize)
3382 template <class CharT, class Traits, class Engine,
3383 std::enable_if_t<detail::is_serializable_engine_v<Engine>>* = nullptr>
3384 std::basic_istream<CharT, Traits>&
3385 operator>>(std::basic_istream<CharT, Traits>& is, Engine& engine)
3386 {
3387 typename Engine::state_type state{};
3388 std::size_t i = 0;
3389 for (; i < state.size() && is; ++i)
3390 is >> state[i];
3391
3392 if (i == state.size() && is)
3393 {
3394 engine.deserialize(state);
3395 }
3396 else
3397 {
3398 is.setstate(std::ios_base::failbit);
3399 }
3400 return is;
3401 }
3402
3403}
#define RANDX_NODISCARD_CXX20
定义 RandX_Cpp17.hpp:124
ChaCha20 密码学安全伪随机数生成器(CSPRNG),64 位输出,符合 RFC 8439。
定义 RandX.hpp:680
ChaCha20(const ChaCha20 &)=delete
ChaCha20 & operator=(ChaCha20 &&other) noexcept
ChaCha20 & operator=(const ChaCha20 &)=delete
static RANDX_NODISCARD_CXX20 constexpr result_type max() noexcept
输出范围上界
定义 RandX_Cpp17.hpp:792
ChaCha20(ChaCha20 &&other) noexcept
~ChaCha20() noexcept
constexpr RomuDuoJr(std::uint64_t seed=DefaultSeed) noexcept
以指定种子构造引擎
RANDX_NODISCARD_CXX20 constexpr RomuDuoJr(SeedSeq &seq)
从 std::seed_seq 播种
friend bool operator!=(const RomuDuoJr &lhs, const RomuDuoJr &rhs) noexcept
定义 RandX_Cpp17.hpp:717
constexpr RomuDuoJr(state_type state) noexcept
从状态数组直接构造
constexpr result_type operator()() noexcept
生成下一个 64 位随机数
friend bool operator!=(const SFC64 &lhs, const SFC64 &rhs) noexcept
定义 RandX_Cpp17.hpp:636
RANDX_NODISCARD_CXX20 constexpr SFC64(SeedSeq &seq)
从 std::seed_seq 播种
constexpr SFC64(state_type state) noexcept
从状态数组直接构造
constexpr SFC64(std::uint64_t seed=DefaultSeed) noexcept
以指定种子构造引擎
constexpr result_type operator()() noexcept
生成下一个 64 位随机数
SplitMix64 伪随机数生成器,64 位输出,周期 2^64。
定义 RandX.hpp:165
constexpr result_type operator()() noexcept
生成下一个 64 位随机数
RANDX_NODISCARD_CXX20 constexpr SplitMix64(state_type state=DefaultSeed) noexcept
以指定状态构造引擎
friend bool operator!=(const SplitMix64 &lhs, const SplitMix64 &rhs) noexcept
定义 RandX_Cpp17.hpp:217
RANDX_NODISCARD_CXX20 constexpr SplitMix64(SeedSeq &seq)
从 std::seed_seq 播种
RANDX_NODISCARD_CXX20 constexpr Xoroshiro128StarStar(state_type state) noexcept
从状态数组直接构造
friend bool operator!=(const Xoroshiro128StarStar &lhs, const Xoroshiro128StarStar &rhs) noexcept
定义 RandX_Cpp17.hpp:393
constexpr result_type operator()() noexcept
生成下一个 64 位随机数
RANDX_NODISCARD_CXX20 constexpr Xoroshiro128StarStar(SeedSeq &seq)
从 std::seed_seq 播种
RANDX_NODISCARD_CXX20 constexpr Xoroshiro128StarStar(std::uint64_t seed=DefaultSeed) noexcept
以指定种子构造引擎
RANDX_NODISCARD_CXX20 constexpr Xoroshiro64StarStar(state_type state) noexcept
从状态数组直接构造
friend bool operator!=(const Xoroshiro64StarStar &lhs, const Xoroshiro64StarStar &rhs) noexcept
定义 RandX_Cpp17.hpp:559
RANDX_NODISCARD_CXX20 constexpr Xoroshiro64StarStar(std::uint64_t seed=DefaultSeed) noexcept
以指定种子构造引擎
constexpr result_type operator()() noexcept
生成下一个 32 位随机数
RANDX_NODISCARD_CXX20 constexpr Xoroshiro64StarStar(SeedSeq &seq)
从 std::seed_seq 播种
RANDX_NODISCARD_CXX20 constexpr Xoshiro128StarStar(std::uint64_t seed=DefaultSeed) noexcept
以指定种子构造引擎
constexpr result_type operator()() noexcept
生成下一个 32 位随机数
RANDX_NODISCARD_CXX20 constexpr Xoshiro128StarStar(SeedSeq &seq)
从 std::seed_seq 播种
RANDX_NODISCARD_CXX20 constexpr Xoshiro128StarStar(state_type state) noexcept
从状态数组直接构造
friend bool operator!=(const Xoshiro128StarStar &lhs, const Xoshiro128StarStar &rhs) noexcept
定义 RandX_Cpp17.hpp:481
Xoshiro256** 伪随机数生成器,64 位输出,周期 2^256-1。
定义 RandX.hpp:235
RANDX_NODISCARD_CXX20 constexpr Xoshiro256StarStar(state_type state) noexcept
从状态数组直接构造
friend bool operator!=(const Xoshiro256StarStar &lhs, const Xoshiro256StarStar &rhs) noexcept
定义 RandX_Cpp17.hpp:305
RANDX_NODISCARD_CXX20 constexpr Xoshiro256StarStar(SeedSeq &seq)
从 std::seed_seq 播种
RANDX_NODISCARD_CXX20 constexpr Xoshiro256StarStar(std::uint64_t seed=DefaultSeed) noexcept
以指定种子构造引擎
constexpr result_type operator()() noexcept
生成下一个 64 位随机数
bool RandBernoulli(double p=0.5)
伯努利分布(RandBool 的别名封装,对齐 <random> 命名)
定义 RandX.hpp:2045
bool RandBool(double p=0.5)
生成随机布尔值
定义 RandX.hpp:2021
T RandReal(T min=T{0}, T max=T{1})
生成 [min, max) 范围内的随机浮点数
定义 RandX.hpp:2010
CharT RandChar(CharT min, CharT max)
生成 [min, max] 范围内的随机字符
定义 RandX.hpp:2070
T RandInt(T min, T max)
生成 [min, max] 范围内的随机整数
定义 RandX.hpp:1986
decltype(auto) RandElement(Container &c)
从容器中随机取一个元素(左值容器,返回引用)
定义 RandX.hpp:2129
std::uint64_t SecureSeed()
生成密码学安全的 64 位随机种子
定义 RandX.hpp:1730
void SecureRandomBytes(void *buf, std::size_t n)
用 OS 密码学熵源填充 [buf, buf+n) 字节
定义 RandX.hpp:1720
void ReseedRandom()
重置默认引擎为真随机种子
定义 RandX.hpp:1969
bool IsOsCryptoEntropyAvailable() noexcept
检测 OS 密码学熵源是否可用
定义 RandX.hpp:1741
void Reseed(std::uint64_t seed)
重置默认引擎的种子(用于测试复现)
定义 RandX.hpp:1963
void RandFill(It first, It last, T min, T max)
用 [min, max] 范围的随机整数填充迭代器区间
定义 RandX.hpp:2277
void RandShuffle(Container &&c)
随机打乱容器
定义 RandX.hpp:2263
WeightContainer::size_type RandWeighted(const WeightContainer &weights)
按权重随机选取索引
定义 RandX.hpp:2413
CharSet
定义 RandX.hpp:2505
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
constexpr SplitMix64(state_type state=DefaultSeed) noexcept
以指定状态构造引擎
定义 RandX.hpp:1037
static constexpr result_type max() noexcept
输出范围上界
定义 RandX.hpp:1652
constexpr double DoubleFromBits(Uint64 i) noexcept
定义 RandX.hpp:759
std::uint64_t result_type
输出类型
定义 RandX.hpp:239
constexpr Xoroshiro128StarStar(std::uint64_t seed=DefaultSeed) noexcept
以指定种子构造引擎
定义 RandX.hpp:1225
ChaCha20 & operator=(const ChaCha20 &)=delete
std::array< std::uint32_t, 4 > state_type
状态类型(4×uint32)
定义 RandX.hpp:394
Xoshiro256StarStar & DefaultEngine()
定义 RandX.hpp:1704
constexpr state_type serialize() const noexcept
序列化引擎状态
定义 RandX.hpp:1205
void discard(unsigned long long n)
跳过 n 个输出
定义 RandX.hpp:1956
constexpr result_type operator()() noexcept
生成下一个 64 位随机数
定义 RandX.hpp:1571
constexpr result_type operator()() noexcept
生成下一个 64 位随机数
定义 RandX.hpp:1639
static constexpr result_type min() noexcept
输出范围下界
定义 RandX.hpp:1195
constexpr void deserialize(state_type state) noexcept
从状态恢复引擎
定义 RandX.hpp:1662
constexpr state_type serialize() const noexcept
序列化引擎状态
定义 RandX.hpp:1520
constexpr SFC64(std::uint64_t seed=DefaultSeed) noexcept
以指定种子构造引擎
定义 RandX.hpp:1541
static constexpr result_type min() noexcept
输出范围下界
定义 RandX.hpp:1580
std::array< std::uint64_t, 4 > state_type
状态类型(4×uint64)
定义 RandX.hpp:238
std::uint64_t result_type
输出类型
定义 RandX.hpp:169
std::array< std::uint64_t, 4 > state_type
状态类型(4×uint64)
定义 RandX.hpp:540
std::uint64_t RandomSeed()
生成非确定性的 64 位种子
定义 RandX.hpp:1683
constexpr result_type operator()() noexcept
生成下一个 64 位随机数
定义 RandX.hpp:1122
void reseed()
从 OS 熵重新播种
定义 RandX.hpp:1914
constexpr float FloatFromBits(Uint32 i) noexcept
定义 RandX.hpp:753
constexpr void deserialize(state_type state) noexcept
从状态恢复引擎
定义 RandX.hpp:1085
constexpr Xoroshiro64StarStar(std::uint64_t seed=DefaultSeed) noexcept
以指定种子构造引擎
定义 RandX.hpp:1468
constexpr void deserialize(state_type state) noexcept
从状态恢复引擎
定义 RandX.hpp:1322
std::uint64_t result_type
输出类型
定义 RandX.hpp:683
constexpr void jump() noexcept
前进 2^64 步,用于创建并行子序列
定义 RandX.hpp:1259
std::uint32_t result_type
输出类型
定义 RandX.hpp:395
std::uint64_t result_type
输出类型
定义 RandX.hpp:317
constexpr void deserialize(state_type state) noexcept
从状态恢复引擎
定义 RandX.hpp:1595
constexpr void deserialize(state_type state) noexcept
从状态恢复引擎
定义 RandX.hpp:1525
constexpr state_type serialize() const noexcept
序列化引擎状态
定义 RandX.hpp:1590
constexpr void discard(unsigned long long n) noexcept
跳过 n 个输出
定义 RandX.hpp:1669
std::uint64_t result_type
输出类型
定义 RandX.hpp:541
constexpr void discard(unsigned long long n) noexcept
跳过 n 个输出
定义 RandX.hpp:1459
std::uint64_t state_type
状态类型(1×uint64)
定义 RandX.hpp:168
static constexpr result_type max() noexcept
输出范围上界
定义 RandX.hpp:732
constexpr void deserialize(state_type state) noexcept
从状态恢复引擎
定义 RandX.hpp:1453
static constexpr result_type max() noexcept
输出范围上界
定义 RandX.hpp:1075
static constexpr result_type min() noexcept
输出范围下界
定义 RandX.hpp:1647
std::uint64_t result_type
输出类型
定义 RandX.hpp:612
static constexpr result_type max() noexcept
输出范围上界
定义 RandX.hpp:1515
~ChaCha20() noexcept
定义 RandX.hpp:1791
static constexpr result_type max() noexcept
输出范围上界
定义 RandX.hpp:1200
constexpr state_type serialize() const noexcept
序列化引擎状态
定义 RandX.hpp:1317
constexpr void longJump() noexcept
前进 2^96 步,用于创建更稀疏的并行子序列
定义 RandX.hpp:1408
constexpr void discard(unsigned long long n) noexcept
跳过 n 个输出
定义 RandX.hpp:1531
constexpr void discard(unsigned long long n) noexcept
跳过 n 个输出
定义 RandX.hpp:1216
constexpr void discard(unsigned long long n) noexcept
跳过 n 个输出
定义 RandX.hpp:1328
T RandChiSquared(T n=T{1})
生成卡方分布随机数
定义 RandX.hpp:3132
std::string RandString(std::size_t length, std::string_view charset="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
生成指定长度的随机字符串
定义 RandX.hpp:2847
T RandExtremeValue(T a=T{0}, T b=T{1})
生成极值分布(Gumbel)随机数
定义 RandX.hpp:3106
T RandFisherF(T m=T{1}, T n=T{1})
生成 Fisher F 分布随机数
定义 RandX.hpp:3183
T RandCauchy(T a=T{0}, T b=T{1})
生成柯西分布随机数
定义 RandX.hpp:3052
T RandStudentT(T n=T{1})
生成学生 t 分布随机数
定义 RandX.hpp:3157
T RandGamma(T alpha=T{1}, T beta=T{1})
生成伽马分布随机数
定义 RandX.hpp:2946
T RandWeibull(T a=T{1}, T b=T{1})
生成韦布尔分布随机数
定义 RandX.hpp:3079
T RandExp(T lambda=T{1})
生成指数分布随机数
定义 RandX.hpp:2893
T RandLogNormal(T mean=T{0}, T stddev=T{1})
生成对数正态分布随机数
定义 RandX.hpp:3000
T RandBeta(T a=T{1}, T b=T{1})
生成 Beta 分布随机数
定义 RandX.hpp:3211
constexpr Engine MakeStreamEngine(std::uint64_t streamId, std::uint64_t seed=DefaultSeed)
从同一种子创建第 streamId 个不重叠子序列的引擎
定义 RandX.hpp:3308
T RandBinomial(T t=1, double p=0.5)
生成二项分布随机数
定义 RandX.hpp:2973
T RandGeometric(double p=0.5)
生成几何分布随机数(首次成功前的失败次数)
定义 RandX.hpp:3026
T RandPoisson(double mean=1.0)
生成泊松分布随机数
定义 RandX.hpp:2918
std::string RandUUID(Engine &engine)
生成随机 UUID v4 字符串
定义 RandX.hpp:3266
定义 RandX.hpp:765
bool GetOsEntropyBytes(void *buf, std::size_t n) noexcept
定义 RandX.hpp:832
constexpr std::uint32_t ChaCha20Constants[4]
定义 RandX.hpp:894
constexpr bool is_rand_fillable_v
定义 RandX_Cpp17.hpp:1707
bool HardwareRand64(std::uint64_t &out) noexcept
定义 RandX.hpp:804
constexpr bool is_serializable_engine_v
定义 RandX_Cpp17.hpp:1743
constexpr std::uint64_t ChaCha20ReseedThreshold
定义 RandX.hpp:899
static void ChaCha20QuarterRound(std::uint32_t &a, std::uint32_t &b, std::uint32_t &c, std::uint32_t &d) noexcept
定义 RandX.hpp:902
constexpr bool is_random_access_iterator_v
定义 RandX_Cpp17.hpp:1661
constexpr bool is_input_iterator_v
定义 RandX_Cpp17.hpp:1665
constexpr bool is_character_v
定义 RandX_Cpp17.hpp:1638
std::uint64_t Generate64Bits(Engine &engine)
定义 RandX.hpp:913
static constexpr std::uint64_t RotL(const std::uint64_t x, const int s) noexcept
定义 RandX.hpp:767
static constexpr bool IsAllZero(const std::array< std::uint64_t, N > &state) noexcept
定义 RandX.hpp:788
bool HasCryptoGradeOsEntropy() noexcept
定义 RandX.hpp:883
constexpr bool is_random_access_container_v
定义 RandX_Cpp17.hpp:1679
static void SecureWipe(void *ptr, std::size_t len) noexcept
定义 RandX.hpp:779
constexpr std::uint64_t HashSetThresholdK
定义 RandX.hpp:2493
constexpr bool is_indexable_state_v
定义 RandX_Cpp17.hpp:1723
定义 RandX.hpp:138
constexpr std::uint64_t DefaultSeed
定义 RandX.hpp:140
定义 RandX_Cpp17.hpp:1618
定义 RandX_Cpp17.hpp:1635
定义 RandX_Cpp17.hpp:1711
定义 RandX_Cpp17.hpp:1652
定义 RandX_Cpp17.hpp:1697
定义 RandX_Cpp17.hpp:1642
定义 RandX_Cpp17.hpp:1727