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 <cmath>
81# include <limits>
82# include <type_traits>
83# include <random>
84# include <algorithm>
85# include <cassert>
86# include <string>
87# include <string_view>
88# include <unordered_set>
89# include <vector>
90# include <stdexcept>
91# include <chrono> // std::chrono(RandomSeed 时间戳兜底用)
92# include <atomic> // std::atomic(RandomSeed 兜底计数)
93# include <functional>// std::hash(RandomSeed 线程 Hash)
94# include <thread> // std::this_thread(RandomSeed 线程 ID)
95# include <ios> // std::ios_base::failbit(operator>> 所需)
96# include <istream> // std::basic_istream(operator>> 所需完整类型)
97# include <ostream> // std::basic_ostream(operator<< 所需完整类型)
98# if defined(_MSC_VER) && (defined(__x86_64__) || defined(_M_X64))
99# include <immintrin.h>
100# include <intrin.h>
101# endif
102// ── A3 跨平台 OS 熵源头文件(条件包含) ──
103# if defined(_WIN32) && __has_include(<bcrypt.h>)
104// bcrypt.h 依赖 <windows.h> 提供的 ULONG/NTSTATUS 等类型(MSVC 和 MinGW 均需)
105// NOMINMAX 阻止 <windows.h> 定义 min/max 宏(与引擎的 min()/max() 方法冲突)
106# ifndef WIN32_LEAN_AND_MEAN
107# define WIN32_LEAN_AND_MEAN
108# endif
109# ifndef NOMINMAX
110# define NOMINMAX
111# endif
112# include <windows.h>
113# include <bcrypt.h>
114# pragma comment(lib, "bcrypt.lib") // 仅 MSVC 生效
115// MinGW 不支持 #pragma comment(lib),须手动添加 -lbcrypt 链接选项
116# if(defined(__MINGW32__) || defined(__MINGW64__)) && !defined(RANDX_SUPPRESS_LINK_HINT)
117# pragma message("RandX: MinGW 需手动链接 bcrypt(编译命令添加 -lbcrypt)")
118# endif
119# elif defined(__linux__) && __has_include(<sys/random.h>)
120# include <sys/random.h>
121# include <cerrno>
122# elif defined(__APPLE__)
123# include <TargetConditionals.h>
124# if TARGET_OS_IPHONE
125# if __has_include(<Security/SecRandom.h>)
126# include <Security/SecRandom.h>
127# endif
128# elif __has_include(<Security/Security.h>)
129# include <Security/Security.h>
130# endif
131# endif
132# include <chrono> // std::chrono(RandomSeed 时间戳兜底用)
133# include <cstring> // std::memcpy(std::random_device 回退路径用)
134# if __has_cpp_attribute(nodiscard) >= 201907L
135# define RANDX_NODISCARD_CXX20 [[nodiscard]]
136# else
137# define RANDX_NODISCARD_CXX20
138# endif
139
140namespace RandX
141{
142 // 生成器的默认种子值
143 inline constexpr std::uint64_t DefaultSeed = 1234567890ULL;
144
145 // 将给定的 uint32 值 `i` 转换为 32 位浮点
146 // 范围在 [0.0f, 1.0f) 的数值
147 template <class Uint32, std::enable_if_t<std::is_same_v<Uint32, std::uint32_t>>* = nullptr>
148 [[nodiscard]]
149 inline constexpr float FloatFromBits(Uint32 i) noexcept;
150
151 // 将给定的 uint64 值 `i` 转换为 64 位浮点
152 // 范围在 [0.0, 1.0) 的数值
153 template <class Uint64, std::enable_if_t<std::is_same_v<Uint64, std::uint64_t>>* = nullptr>
154 [[nodiscard]]
155 inline constexpr double DoubleFromBits(Uint64 i) noexcept;
156
157 // ── 引擎基础设施(提前定义,供 EngineBase CRTP 基类使用) ──
158 namespace detail
159 {
160 [[nodiscard]]
161 inline constexpr std::uint64_t RotL(const std::uint64_t x, const int s) noexcept
162 {
163 const int count = s & 63;
164 return count == 0 ? x : ((x << count) | (x >> (64 - count)));
165 }
166
167 [[nodiscard]]
168 inline constexpr std::uint32_t RotL(const std::uint32_t x, const int s) noexcept
169 {
170 const int count = s & 31;
171 return count == 0 ? x : ((x << count) | (x >> (32 - count)));
172 }
173
174 template <std::size_t N>
175 [[nodiscard]]
176 inline constexpr bool IsAllZero(const std::array<std::uint64_t, N>& state) noexcept
177 {
178 for (const auto& s : state) { if (s != 0) return false; }
179 return true;
180 }
181
182 template <std::size_t N>
183 [[nodiscard]]
184 inline constexpr bool IsAllZero(const std::array<std::uint32_t, N>& state) noexcept
185 {
186 for (const auto& s : state) { if (s != 0) return false; }
187 return true;
188 }
189
190 template <typename State>
191 [[nodiscard]]
192 inline constexpr bool IsValidState(const State& state) noexcept
193 {
194 return !IsAllZero(state);
195 }
196 }
197
200
209 class SplitMix64
210 {
211 public:
212
213 using state_type = std::uint64_t;
214 using result_type = std::uint64_t;
215
219 explicit constexpr SplitMix64(state_type state = DefaultSeed) noexcept;
220
223 template <class SeedSeq,
224 std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>, SplitMix64>>* = nullptr>
226 explicit constexpr SplitMix64(SeedSeq& seq);
227
230 constexpr result_type operator()() noexcept;
231
234 constexpr void discard(unsigned long long n) noexcept;
235
239 template <std::size_t N>
240 [[nodiscard]]
241 constexpr std::array<std::uint64_t, N> generateSeedSequence() noexcept;
242
245 [[nodiscard]]
246 static constexpr result_type min() noexcept;
247
250 [[nodiscard]]
251 static constexpr result_type max() noexcept;
252
256 [[nodiscard]]
257 constexpr state_type serialize() const noexcept;
258
262 constexpr void deserialize(state_type state) noexcept;
263
264 [[nodiscard]]
265 friend bool operator ==(const SplitMix64& lhs, const SplitMix64& rhs) noexcept
266 {
267 return (lhs.m_state == rhs.m_state);
268 }
269
270 [[nodiscard]]
271 friend bool operator !=(const SplitMix64& lhs, const SplitMix64& rhs) noexcept
272 {
273 return (lhs.m_state != rhs.m_state);
274 }
275
276 private:
277
278 state_type m_state;
279 };
280
281 // ── EngineBase CRTP 基类 ──
282 // 为数组状态引擎提供公共接口:min/max/discard/serialize/比较/构造/jumpPoly
283 // SplitMix64(标量状态)和 ChaCha20(CSPRNG)不继承此基类
284 namespace detail
285 {
286 template <class Derived, class ResultType, std::size_t N>
287 struct EngineBase
288 {
289 using result_type = ResultType;
290 using state_type = std::array<ResultType, N>;
291
292 // --- 公共接口 ---
293
294 [[nodiscard]]
295 static constexpr result_type min() noexcept
296 {
297 return std::numeric_limits<result_type>::lowest();
298 }
299
300 [[nodiscard]]
301 static constexpr result_type max() noexcept
302 {
303 return std::numeric_limits<result_type>::max();
304 }
305
306 constexpr void discard(unsigned long long z) noexcept
307 {
308 for (unsigned long long i = 0; i < z; ++i)
309 static_cast<Derived*>(this)->operator()();
310 }
311
312 [[nodiscard]]
313 constexpr state_type serialize() const noexcept
314 {
315 return s_;
316 }
317
318 constexpr void deserialize(const state_type& s) noexcept
319 {
320 s_ = s;
321 if (IsAllZero(s_))
322 {
323 s_[0] = static_cast<ResultType>(1);
324 }
325 assert(!IsAllZero(s_) && "absorbing all-zero state");
326 }
327
328 // C++17: 手写比较运算符
329 friend bool operator==(const EngineBase& lhs, const EngineBase& rhs) noexcept
330 {
331 return lhs.s_ == rhs.s_;
332 }
333
334 friend bool operator!=(const EngineBase& lhs, const EngineBase& rhs) noexcept
335 {
336 return lhs.s_ != rhs.s_;
337 }
338
339 protected:
340
341 static constexpr int Bits = static_cast<int>(sizeof(ResultType) * 8);
342
343 EngineBase() = default;
344
345 // State 构造(用户直接传入,包含 Release/Debug 全零状态静默修正)
346 explicit constexpr EngineBase(const state_type& state) noexcept
347 : s_(state)
348 {
349 if (IsAllZero(s_))
350 {
351 s_[0] = static_cast<ResultType>(1);
352 }
353 assert(!IsAllZero(s_) && "absorbing all-zero state");
354 }
355
356 // SeedSeq 构造(SFINAE 排除 state_type 和 Derived)
357 template <class SeedSeq,
358 std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>, state_type>
359 && !std::is_same_v<std::decay_t<SeedSeq>, Derived>>* = nullptr>
360 explicit constexpr EngineBase(SeedSeq& seq)
361 {
362 if constexpr (sizeof(result_type) == 8)
363 {
364 std::array<std::uint32_t, N * 2> raw;
365 seq.generate(raw.begin(), raw.end());
366 for (std::size_t i = 0; i < N; ++i)
367 s_[i] = (static_cast<result_type>(raw[2 * i]) << 32) | raw[2 * i + 1];
368 }
369 else
370 {
371 std::array<std::uint32_t, N> raw;
372 seq.generate(raw.begin(), raw.end());
373 for (std::size_t i = 0; i < N; ++i)
374 s_[i] = static_cast<result_type>(raw[i]);
375 }
376 if (IsAllZero(s_)) s_[0] = 1;
377 }
378
379 // 单值播种(SplitMix64 扩展,等价于 generateSeedSequence<N>)
380 explicit constexpr EngineBase(std::uint64_t seed) noexcept
381 {
382 SplitMix64 sm{ seed };
383 for (std::size_t i = 0; i < N; ++i)
384 s_[i] = static_cast<result_type>(sm());
385 if (IsAllZero(s_)) s_[0] = 1;
386 }
387
388 // jump 多项式通用实现(constexpr,供 MakeStreamEngine 编译期调用)
389 template <std::size_t K>
390 constexpr void jumpPoly(const ResultType (&poly)[K]) noexcept
391 {
392 std::array<ResultType, N> acc{};
393 for (std::size_t i = 0; i < K; ++i)
394 for (int b = 0; b < Bits; ++b)
395 {
396 if (poly[i] & (ResultType{ 1 } << b))
397 for (std::size_t j = 0; j < N; ++j)
398 acc[j] ^= s_[j];
399 static_cast<Derived*>(this)->operator()();
400 }
401 s_ = acc;
402 }
403
404 state_type s_{};
405 };
406 }
407
417 : public detail::EngineBase<Xoshiro256StarStar, std::uint64_t, 4>
418 {
419 using Base = detail::EngineBase<Xoshiro256StarStar, std::uint64_t, 4>;
420 public:
421
422 using typename Base::result_type;
423 using typename Base::state_type;
424
426 constexpr Xoshiro256StarStar() noexcept : Base(DefaultSeed) {}
427
431 explicit constexpr Xoshiro256StarStar(std::uint64_t seed) noexcept
432 : Base(seed) {}
433
436 template <class SeedSeq,
437 std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>, Xoshiro256StarStar>>* = nullptr>
439 explicit constexpr Xoshiro256StarStar(SeedSeq& seq)
440 : Base(seq) {}
441
445 explicit constexpr Xoshiro256StarStar(state_type state) noexcept
446 : Base(state) {}
447
450 constexpr result_type operator()() noexcept;
451
455 constexpr void jump() noexcept;
456
460 constexpr void longJump() noexcept;
461 };
462
472 : public detail::EngineBase<Xoroshiro128StarStar, std::uint64_t, 2>
473 {
475 public:
476
477 using typename Base::result_type;
478 using typename Base::state_type;
479
481 constexpr Xoroshiro128StarStar() noexcept : Base(DefaultSeed) {}
482
486 explicit constexpr Xoroshiro128StarStar(std::uint64_t seed) noexcept
487 : Base(seed) {}
488
491 template <class SeedSeq,
492 std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>, Xoroshiro128StarStar>>* = nullptr>
494 explicit constexpr Xoroshiro128StarStar(SeedSeq& seq)
495 : Base(seq) {}
496
500 explicit constexpr Xoroshiro128StarStar(state_type state) noexcept
501 : Base(state) {}
502
505 constexpr result_type operator()() noexcept;
506
510 constexpr void jump() noexcept;
511
515 constexpr void longJump() noexcept;
516 };
517
527 : public detail::EngineBase<Xoshiro128StarStar, std::uint32_t, 4>
528 {
530 public:
531
532 using typename Base::result_type;
533 using typename Base::state_type;
534
536 constexpr Xoshiro128StarStar() noexcept : Base(DefaultSeed) {}
537
541 explicit constexpr Xoshiro128StarStar(std::uint64_t seed) noexcept
542 : Base(seed) {}
543
546 template <class SeedSeq,
547 std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>, Xoshiro128StarStar>>* = nullptr>
549 explicit constexpr Xoshiro128StarStar(SeedSeq& seq)
550 : Base(seq) {}
551
555 explicit constexpr Xoshiro128StarStar(state_type state) noexcept
556 : Base(state) {}
557
560 constexpr result_type operator()() noexcept;
561
565 constexpr void jump() noexcept;
566
570 constexpr void longJump() noexcept;
571 };
572
582 : public detail::EngineBase<Xoroshiro64StarStar, std::uint32_t, 2>
583 {
585 public:
586
587 using typename Base::result_type;
588 using typename Base::state_type;
589
591 constexpr Xoroshiro64StarStar() noexcept : Base(DefaultSeed) {}
592
596 explicit constexpr Xoroshiro64StarStar(std::uint64_t seed) noexcept
597 : Base(seed) {}
598
601 template <class SeedSeq,
602 std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>, Xoroshiro64StarStar>>* = nullptr>
604 explicit constexpr Xoroshiro64StarStar(SeedSeq& seq)
605 : Base(seq) {}
606
610 explicit constexpr Xoroshiro64StarStar(state_type state) noexcept
611 : Base(state) {}
612
615 constexpr result_type operator()() noexcept;
616 };
625 class SFC64
626 : public detail::EngineBase<SFC64, std::uint64_t, 4>
627 {
629 public:
630
631 using typename Base::result_type;
632 using typename Base::state_type;
633
635 constexpr SFC64() noexcept : SFC64(DefaultSeed) {}
636
640 explicit constexpr SFC64(std::uint64_t seed) noexcept;
641
644 template <class SeedSeq,
645 std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>, SFC64>>* = nullptr>
647 explicit constexpr SFC64(SeedSeq& seq);
648
652 explicit constexpr SFC64(state_type state) noexcept
653 : Base(state) {}
654
657 constexpr result_type operator()() noexcept;
658 };
659
668 class RomuDuoJr
669 : public detail::EngineBase<RomuDuoJr, std::uint64_t, 2>
670 {
672 public:
673
674 using typename Base::result_type;
675 using typename Base::state_type;
676
678 constexpr RomuDuoJr() noexcept : Base(DefaultSeed) {}
679
683 explicit constexpr RomuDuoJr(std::uint64_t seed) noexcept
684 : Base(seed) {}
685
688 template <class SeedSeq,
689 std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>, RomuDuoJr>>* = nullptr>
691 explicit constexpr RomuDuoJr(SeedSeq& seq)
692 : Base(seq) {}
693
697 explicit constexpr RomuDuoJr(state_type state) noexcept
698 : Base(state) {}
699
702 constexpr result_type operator()() noexcept;
703 };
704
705 // ── 全 PRNG 引擎 TLS 可平凡析构(Trivially Destructible)编译期静态断言 ──
706 static_assert(std::is_trivially_destructible_v<Xoshiro256StarStar>, "Xoshiro256StarStar must be trivially destructible for safe TLS.");
707 static_assert(std::is_trivially_destructible_v<Xoroshiro128StarStar>, "Xoroshiro128StarStar must be trivially destructible for safe TLS.");
708 static_assert(std::is_trivially_destructible_v<Xoshiro128StarStar>, "Xoshiro128StarStar must be trivially destructible for safe TLS.");
709 static_assert(std::is_trivially_destructible_v<Xoroshiro64StarStar>, "Xoroshiro64StarStar must be trivially destructible for safe TLS.");
710 static_assert(std::is_trivially_destructible_v<SplitMix64>, "SplitMix64 must be trivially destructible for safe TLS.");
711 static_assert(std::is_trivially_destructible_v<SFC64>, "SFC64 must be trivially destructible for safe TLS.");
712 static_assert(std::is_trivially_destructible_v<RomuDuoJr>, "RomuDuoJr must be trivially destructible for safe TLS.");
713
725 class ChaCha20
726 {
727 public:
728
729 using result_type = std::uint64_t;
730
731 ChaCha20(const ChaCha20&) = delete;
732 ChaCha20& operator=(const ChaCha20&) = delete;
733 ChaCha20(ChaCha20&& other) noexcept;
734 ChaCha20& operator=(ChaCha20&& other) noexcept;
735 ~ChaCha20() noexcept;
736
740
745 explicit ChaCha20(std::uint64_t seed);
746
754 ChaCha20(const std::uint8_t* key, std::size_t keyLen,
755 const std::uint8_t* nonce, std::size_t nonceLen,
756 std::uint32_t counter = 0);
757
760 result_type operator()();
761
764 void discard(unsigned long long n);
765
768 void reseed();
769
773 static constexpr result_type min() noexcept { return 0; }
774
778 static constexpr result_type max() noexcept { return UINT64_MAX; }
779
780 // 不提供:serialize/deserialize, operator<</>>, jump/longJump(CSPRNG 安全约束)
781
782 private:
783
784 std::array<std::uint32_t, 12> m_state; // key(8) + counter(1) + nonce(3),常数省略(generateBlock 时补齐)
785 std::array<std::uint8_t, 64> m_buffer; // 当前 block 的字节缓存
786 std::size_t m_bufferPos; // 缓存消费位置 [0, 64),==64 时触发新 block
787 std::uint64_t m_bytesSinceReseed; // 自上次 reseed 以来输出的字节数
788 bool m_autoReseed{ false }; // 是否在满 1MB 后自动从 OS 熵重新播种(仅默认无参构造函数启用)
789
790 void generateBlock(); // 跑一次 ChaCha20 block 函数填充 m_buffer
791 void reseedIfNecessary(); // m_bytesSinceReseed >= 阈值时自动 reseed
792 };
793
794 // ── sizeof 守卫:防止引擎 ABI 意外变化 ──
795 static_assert(sizeof(Xoshiro256StarStar) == 32, "Xoshiro256StarStar size changed");
796 static_assert(sizeof(Xoroshiro128StarStar) == 16, "Xoroshiro128StarStar size changed");
797 static_assert(sizeof(Xoshiro128StarStar) == 16, "Xoshiro128StarStar size changed");
798 static_assert(sizeof(Xoroshiro64StarStar) == 8, "Xoroshiro64StarStar size changed");
799 static_assert(sizeof(SFC64) == 32, "SFC64 size changed");
800 static_assert(sizeof(RomuDuoJr) == 16, "RomuDuoJr size changed");
801 static_assert(sizeof(SplitMix64) == 8, "SplitMix64 size changed");
802}
803
805
806namespace RandX
807{
808 template <class Uint32, std::enable_if_t<std::is_same_v<Uint32, std::uint32_t>>*>
809 inline constexpr float FloatFromBits(const Uint32 i) noexcept
810 {
811 return (i >> 8) * 0x1.0p-24f;
812 }
813
814 template <class Uint64, std::enable_if_t<std::is_same_v<Uint64, std::uint64_t>>*>
815 inline constexpr double DoubleFromBits(const Uint64 i) noexcept
816 {
817 return (i >> 11) * 0x1.0p-53;
818 }
819
820 namespace detail
821 {
822 // 安全擦除内存(volatile 防止编译器死存储消除)
823 static void SecureWipe(void* ptr, std::size_t len) noexcept
824 {
825 volatile auto* p = static_cast<volatile std::uint8_t*>(ptr);
826 while (len--) *p++ = 0;
827 }
828
829 // 尝试使用 RDRAND 获取 64 位硬件随机数
830 [[nodiscard]]
831 inline bool HardwareRand64(std::uint64_t& out) noexcept
832 {
833#if defined(__x86_64__) || defined(_M_X64)
834 #if defined(__RDRND__)
835 unsigned long long result;
836 if (__builtin_ia32_rdrand64_step(&result))
837 {
838 out = result;
839 return true;
840 }
841 #elif defined(_MSC_VER)
842 int cpuInfo[4] = {0};
843 __cpuid(cpuInfo, 1);
844 if ((cpuInfo[2] & (1 << 30)) != 0)
845 {
846 unsigned long long result = 0;
847 if (_rdrand64_step(&result))
848 {
849 out = result;
850 return true;
851 }
852 }
853 #endif
854#endif
855 (void)out;
856 return false;
857 }
858
859 // ── A3 跨平台 OS 密码学熵源 ──
860 // 用 OS 密码学 API 填充 [buf, buf+n) 字节;成功返回 true。
861 // 平台优先级:Windows BCryptGenRandom → Linux getrandom → macOS SecRandomCopyBytes → std::random_device 兜底
862 // 注:getrandom 可能短读,内部循环直至填满;BCryptGenRandom/SecRandomCopyBytes 一次填满
863 [[nodiscard]]
864 inline bool GetOsEntropyBytes(void* buf, std::size_t n) noexcept
865 {
866 if (n == 0) return true;
867 auto* p = static_cast<std::uint8_t*>(buf);
868
869# if defined(_WIN32) && __has_include(<bcrypt.h>)
870 // Windows: BCryptGenRandom(分块处理 >4GB 时的 ULONG 截断)
871 // NTSTATUS >= 0 即 NT_SUCCESS(使用 BCRYPT_SUCCESS 宏或强转 NTSTATUS 判定)
872 std::size_t filled = 0;
873 while (filled < n)
874 {
875 const ULONG chunkSize = static_cast<ULONG>((std::min)(n - filled, static_cast<std::size_t>((std::numeric_limits<ULONG>::max)())));
876 const auto status = ::BCryptGenRandom(nullptr, p + filled, chunkSize, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
877# if defined(BCRYPT_SUCCESS)
878 if (!BCRYPT_SUCCESS(status)) return false;
879# else
880 if (static_cast<NTSTATUS>(status) < 0) return false;
881# endif
882 filled += chunkSize;
883 }
884 return true;
885
886# elif defined(__linux__) && __has_include(<sys/random.h>)
887 // Linux: getrandom(循环处理短读与 EINTR)
888 std::size_t filled = 0;
889 while (filled < n)
890 {
891 const ssize_t ret = ::getrandom(p + filled, n - filled, 0);
892 if (ret < 0)
893 {
894 if (errno == EINTR) continue; // 被信号打断,重试
895 return false; // ENOSYS/EFAULT 等不可恢复错误
896 }
897 if (ret == 0) return false;
898 filled += static_cast<std::size_t>(ret);
899 }
900 return true;
901
902# elif defined(__APPLE__) && __has_include(<Security/Security.h>)
903 // macOS: SecRandomCopyBytes(一次调用填满)
904 return (::SecRandomCopyBytes(kSecRandomDefault, n, p) == errSecSuccess);
905
906# else
907 // 无可用 OS 密码学熵源 → 返回 false,SecureRandomBytes 将抛出异常
908 // 非安全场景的播种请使用 RandomSeed()(含 random_device → 时间戳回退链)
909 (void)p; (void)n;
910 return false;
911# endif
912 }
913
914 // 返回 true 当且仅当编译期检测到 OS 密码学熵源 API(BCryptGenRandom/getrandom/SecRandomCopyBytes)
915 // 返回 false 表示当前运行在 std::random_device 兜底路径,ChaCha20() 默认构造不保证密码学安全
916 [[nodiscard]]
917 inline bool HasCryptoGradeOsEntropy() noexcept
918 {
919# if (defined(_WIN32) && __has_include(<bcrypt.h>)) || (defined(__linux__) && __has_include(<sys/random.h>)) || (defined(__APPLE__) && __has_include(<Security/Security.h>))
920 return true;
921# else
922 return false;
923# endif
924 }
925
926 // ── A4 ChaCha20 常数与辅助 ──
927 // ChaCha20 常数 "expand 32-byte k"(RFC 8439 §2.3)
928 inline constexpr std::uint32_t ChaCha20Constants[4] = {
929 0x61707865u, 0x3320646eu, 0x79622d32u, 0x6b206574u
930 };
931 // 参考 NIST SP 800-90A reseed_interval 概念(SP 800-90A 涵盖 Hash/HMAC/CTR_DRBG,不含 ChaCha20;
932 // 此处借用其"周期性强制 reseed 提供前向安全"思想,取保守阈值)
933 inline constexpr std::uint64_t ChaCha20ReseedThreshold = 1ULL << 20; // 1 MB
934
935 // ChaCha20 quarter-round(仅 add/xor/rotl,常时间友好)
936 static void ChaCha20QuarterRound(std::uint32_t& a, std::uint32_t& b,
937 std::uint32_t& c, std::uint32_t& d) noexcept
938 {
939 a += b; d ^= a; d = RotL(d, 16);
940 c += d; b ^= c; b = RotL(b, 12);
941 a += b; d ^= a; d = RotL(d, 8);
942 c += d; b ^= c; b = RotL(b, 7);
943 }
944 }
945
947 //
948 // SplitMix64
949 //
950 inline constexpr SplitMix64::SplitMix64(const state_type state) noexcept
951 : m_state(state) {}
952
953 template <class SeedSeq, std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>, SplitMix64>>*>
954 inline constexpr SplitMix64::SplitMix64(SeedSeq& seq)
955 {
956 std::array<std::uint32_t, 2> seeds;
957 seq.generate(seeds.begin(), seeds.end());
958 m_state = (static_cast<std::uint64_t>(seeds[0]) << 32) | seeds[1];
959 }
960
961 inline constexpr SplitMix64::result_type SplitMix64::operator()() noexcept
962 {
963 std::uint64_t z = (m_state += 0x9e3779b97f4a7c15);
964 z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
965 z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
966 return z ^ (z >> 31);
967 }
968
969 template <std::size_t N>
970 inline constexpr std::array<std::uint64_t, N> SplitMix64::generateSeedSequence() noexcept
971 {
972 std::array<std::uint64_t, N> seeds = {};
973
974 for (auto& seed : seeds)
975 {
976 seed = operator()();
977 }
978
979 return seeds;
980 }
981
982 inline constexpr SplitMix64::result_type SplitMix64::min() noexcept
983 {
984 return std::numeric_limits<result_type>::lowest();
985 }
986
987 inline constexpr SplitMix64::result_type SplitMix64::max() noexcept
988 {
989 return std::numeric_limits<result_type>::max();
990 }
991
992 inline constexpr SplitMix64::state_type SplitMix64::serialize() const noexcept
993 {
994 return m_state;
995 }
996
997 inline constexpr void SplitMix64::deserialize(const state_type state) noexcept
998 {
999 m_state = state;
1000 }
1001
1002 inline constexpr void SplitMix64::discard(const unsigned long long n) noexcept
1003 {
1004 for (unsigned long long i = 0; i < n; ++i) { operator()(); }
1005 }
1006
1008 //
1009 // xoshiro256**
1010 //
1012 {
1013 const std::uint64_t result = detail::RotL(s_[1] * 5, 7) * 9;
1014 const std::uint64_t t = s_[1] << 17;
1015 s_[2] ^= s_[0];
1016 s_[3] ^= s_[1];
1017 s_[1] ^= s_[2];
1018 s_[0] ^= s_[3];
1019 s_[2] ^= t;
1020 s_[3] = detail::RotL(s_[3], 45);
1021 return result;
1022 }
1023
1024 inline constexpr void Xoshiro256StarStar::jump() noexcept
1025 {
1026 constexpr std::uint64_t p[] = {
1027 0x180ec6d33cfd0aba, 0xd5a61266f0c9392c,
1028 0xa9582618e03fc9aa, 0x39abdc4529b1661c };
1029 jumpPoly(p);
1030 }
1031
1032 inline constexpr void Xoshiro256StarStar::longJump() noexcept
1033 {
1034 constexpr std::uint64_t p[] = {
1035 0x76e15d3efefdcbbf, 0xc5004e441c522fb3,
1036 0x77710069854ee241, 0x39109bb02acbe635 };
1037 jumpPoly(p);
1038 }
1039
1041 //
1042 // xoroshiro128**
1043 //
1045 {
1046 const std::uint64_t s0 = s_[0];
1047 std::uint64_t s1 = s_[1];
1048 const std::uint64_t result = detail::RotL(s0 * 5, 7) * 9;
1049 s1 ^= s0;
1050 s_[0] = detail::RotL(s0, 24) ^ s1 ^ (s1 << 16);
1051 s_[1] = detail::RotL(s1, 37);
1052 return result;
1053 }
1054
1055 inline constexpr void Xoroshiro128StarStar::jump() noexcept
1056 {
1057 constexpr std::uint64_t p[] = { 0xdf900294d8f554a5, 0x170865df4b3201fc };
1058 jumpPoly(p);
1059 }
1060
1061 inline constexpr void Xoroshiro128StarStar::longJump() noexcept
1062 {
1063 constexpr std::uint64_t p[] = { 0xd2a98b26625eee7b, 0xdddf9b1090aa7ac1 };
1064 jumpPoly(p);
1065 }
1066
1068 //
1069 // xoshiro128**
1070 //
1072 {
1073 const std::uint32_t result = detail::RotL(s_[1] * 5, 7) * 9;
1074 const std::uint32_t t = s_[1] << 9;
1075 s_[2] ^= s_[0];
1076 s_[3] ^= s_[1];
1077 s_[1] ^= s_[2];
1078 s_[0] ^= s_[3];
1079 s_[2] ^= t;
1080 s_[3] = detail::RotL(s_[3], 11);
1081 return result;
1082 }
1083
1084 inline constexpr void Xoshiro128StarStar::jump() noexcept
1085 {
1086 constexpr std::uint32_t p[] = { 0x8764000bu, 0xf542d2d3u, 0x6fa035c3u, 0x77f2db5bu };
1087 jumpPoly(p);
1088 }
1089
1090 inline constexpr void Xoshiro128StarStar::longJump() noexcept
1091 {
1092 constexpr std::uint32_t p[] = { 0xb523952eu, 0x0b6f099fu, 0xccf5a0efu, 0x1c580662u };
1093 jumpPoly(p);
1094 }
1095
1097 //
1098 // xoroshiro64**
1099 //
1101 {
1102 const std::uint32_t s0 = s_[0];
1103 std::uint32_t s1 = s_[1];
1104
1105 const std::uint32_t result = detail::RotL(s0 * 0x9E3779BB, 5) * 5;
1106
1107 s1 ^= s0;
1108 s_[0] = detail::RotL(s0, 26) ^ s1 ^ (s1 << 9);
1109 s_[1] = detail::RotL(s1, 13);
1110
1111 return result;
1112 }
1113
1115 //
1116 // SFC64 (Small Fast Counter)
1117 //
1118 inline constexpr SFC64::SFC64(const std::uint64_t seed) noexcept
1119 : Base()
1120 {
1121 // 使用 SplitMix64 播种 + 12 轮预热
1122 SplitMix64 sm{ seed };
1123 s_[0] = sm();
1124 s_[1] = sm();
1125 s_[2] = sm();
1126 s_[3] = 1;
1127 // 全零状态会导致输出可预测,强制修正
1128 if ((s_[0] | s_[1] | s_[2]) == 0) s_[0] = 0x9E3779B97F4A7C15ULL;
1129 for (int i = 0; i < 12; ++i) { operator()(); }
1130 }
1131
1132 template <class SeedSeq, std::enable_if_t<!std::is_same_v<std::decay_t<SeedSeq>, SFC64>>*>
1133 inline constexpr SFC64::SFC64(SeedSeq& seq)
1134 : Base()
1135 {
1136 std::array<std::uint32_t, 8> seeds;
1137 seq.generate(seeds.begin(), seeds.end());
1138 s_[0] = (static_cast<std::uint64_t>(seeds[0]) << 32) | seeds[1];
1139 s_[1] = (static_cast<std::uint64_t>(seeds[2]) << 32) | seeds[3];
1140 s_[2] = (static_cast<std::uint64_t>(seeds[4]) << 32) | seeds[5];
1141 s_[3] = 1;
1142 // 全零状态会导致输出可预测,强制修正
1143 if ((s_[0] | s_[1] | s_[2]) == 0) s_[0] = 0x9E3779B97F4A7C15ULL;
1144 // 与种子构造函数一致:12 轮预热
1145 for (int i = 0; i < 12; ++i) { operator()(); }
1146 }
1147
1148 inline constexpr SFC64::result_type SFC64::operator()() noexcept
1149 {
1150 const std::uint64_t tmp = s_[0] + s_[1] + s_[3]++;
1151 s_[0] = s_[1] ^ (s_[1] >> 11);
1152 s_[1] = s_[2] + (s_[2] << 3);
1153 s_[2] = detail::RotL(s_[2], 24) + tmp;
1154 return tmp;
1155 }
1156
1158 //
1159 // RomuDuoJr
1160 //
1161 inline constexpr RomuDuoJr::result_type RomuDuoJr::operator()() noexcept
1162 {
1163 const std::uint64_t xp = s_[0];
1164 s_[0] = 15241094284759029579ULL * s_[1];
1165 s_[1] = detail::RotL(s_[1] - xp, 27);
1166 return xp;
1167 }
1168
1170 //
1171 // 多流接口(并行计算)
1172 //
1173
1174 // 从同一种子创建第 streamId 个不重叠子序列的引擎
1175 // 每个流之间间隔 2^128 步(xoshiro256)或 2^64 步(xoroshiro128/xoshiro128)
1176 // 注意:Xoroshiro64 系列无 jump 函数,不支持多流
1177 namespace detail
1178 {
1179 template <class Engine, class = void>
1180 struct HasJump : std::false_type {};
1181 template <class Engine>
1182 struct HasJump<Engine, std::void_t<decltype(std::declval<Engine&>().jump())>> : std::true_type {};
1183
1184 template <class Engine, class = void>
1185 struct HasLongJump : std::false_type {};
1186 template <class Engine>
1187 struct HasLongJump<Engine, std::void_t<decltype(std::declval<Engine&>().longJump())>> : std::true_type {};
1188 }
1189
1190 namespace detail
1191 {
1192 // 字符类型检测(char/wchar_t/char16_t/char32_t,C++20+ 追加 char8_t)
1193 template <class T>
1194 struct is_character : std::bool_constant<
1195 std::is_same_v<T, char>
1196 || std::is_same_v<T, wchar_t>
1197 || std::is_same_v<T, char16_t>
1198 || std::is_same_v<T, char32_t>
1199# if defined(__cpp_char8_t) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
1200 || std::is_same_v<T, char8_t>
1201# endif
1202 > {};
1203
1204 template <class T>
1206
1207 // 检测 It 是否为 random_access 迭代器(void_t 包装避免硬错误)
1208 template <class It, class = void>
1209 struct is_random_access_iterator : std::false_type {};
1210
1211 template <class It>
1212 struct is_random_access_iterator<It, std::void_t<
1213 typename std::iterator_traits<It>::iterator_category>>
1214 : std::is_base_of<std::random_access_iterator_tag,
1215 typename std::iterator_traits<It>::iterator_category> {};
1216
1217 // 检测 It 是否为 input_iterator(正向检测,自动排除 output_iterator_tag)
1218 template <class It, class = void>
1219 struct is_input_iterator : std::false_type {};
1220
1221 template <class It>
1222 struct is_input_iterator<It, std::void_t<
1223 typename std::iterator_traits<It>::iterator_category>>
1224 : std::is_base_of<std::input_iterator_tag,
1225 typename std::iterator_traits<It>::iterator_category> {};
1226
1227 template <class It>
1228 inline constexpr bool is_random_access_iterator_v =
1230
1231 template <class It>
1232 inline constexpr bool is_input_iterator_v =
1234
1235 // 检测 C 是否为 random_access 容器
1236 template <class C, class = void>
1237 struct is_random_access_container : std::false_type {};
1238
1239 template <class C>
1240 struct is_random_access_container<C, std::void_t<
1241 decltype(std::begin(std::declval<C&>())),
1242 decltype(std::end(std::declval<C&>()))>>
1243 : is_random_access_iterator<decltype(std::begin(std::declval<C&>()))> {};
1244
1245 template <class C>
1246 inline constexpr bool is_random_access_container_v =
1248
1249 template <class Engine>
1250 [[nodiscard]]
1251 inline std::uint64_t Generate64Bits(Engine& engine)
1252 {
1253 if (sizeof(typename Engine::result_type) >= 8)
1254 {
1255 return static_cast<std::uint64_t>(engine());
1256 }
1257 const std::uint64_t lo = static_cast<std::uint64_t>(engine());
1258 const std::uint64_t hi = static_cast<std::uint64_t>(engine());
1259 return (hi << 32) | lo;
1260 }
1261
1262 // 检测 *first = T 合法性 + T 为数值类型(RandFill 用)
1263 template <class It, class T, class = void>
1264 struct is_rand_fillable : std::false_type {};
1265
1266 template <class It, class T>
1267 struct is_rand_fillable<It, T, std::void_t<
1268 decltype(*std::declval<It&>() = std::declval<T>())
1269 >> : std::bool_constant<
1270 std::is_integral_v<T> || std::is_floating_point_v<T>
1271 > {};
1272
1273 template <class It, class T>
1275
1276 // 检测 state_type 是否为可索引容器(排除标量如 SplitMix64 的 uint64_t)
1277 template <class S, class = void>
1278 struct is_indexable_state : std::false_type {};
1279
1280 template <class S>
1281 struct is_indexable_state<S, std::void_t<
1282 decltype(std::declval<const S&>().size()),
1283 decltype(std::declval<S&>()[std::size_t{}]),
1284 typename S::value_type
1285 >> : std::is_same<
1286 decltype(std::declval<const S&>().size()),
1287 std::size_t> {};
1288
1289 template <class S>
1291
1292 // 可序列化引擎检测(serialize/deserialize/state_type + state_type 为可索引容器)
1293 template <class E, class = void>
1294 struct is_serializable_engine : std::false_type {};
1295
1296 template <class E>
1297 struct is_serializable_engine<E, std::void_t<
1298 decltype(std::declval<const E&>().serialize()),
1299 decltype(std::declval<E&>().deserialize(
1300 std::declval<typename E::state_type>())),
1301 typename E::state_type
1302 >> : std::bool_constant<
1303 std::is_same_v<
1304 decltype(std::declval<const E&>().serialize()),
1305 typename E::state_type>
1306 && is_indexable_state_v<typename E::state_type>
1307 > {};
1308
1309 template <class E>
1311 }
1312
1313 template <class Engine, std::enable_if_t<detail::HasJump<Engine>::value>* = nullptr>
1314 [[nodiscard]]
1315 inline constexpr Engine MakeStreamEngine(std::uint64_t streamId, std::uint64_t seed = DefaultSeed)
1316 {
1317 Engine rng{ seed };
1319 {
1320 const std::uint64_t longJumps = streamId >> 32;
1321 const std::uint64_t shortJumps = streamId & 0xFFFFFFFFULL;
1322 for (std::uint64_t i = 0; i < longJumps; ++i)
1323 rng.longJump();
1324 for (std::uint64_t i = 0; i < shortJumps; ++i)
1325 rng.jump();
1326 }
1327 else
1328 {
1329 for (std::uint64_t i = 0; i < streamId; ++i)
1330 rng.jump();
1331 }
1332 return rng;
1333 }
1334
1336 //
1337 // 便捷工具函数
1338 //
1339
1340 // 生成非确定性的 64 位种子(优先硬件 RNG,用于统计 PRNG 播种)
1341 // 优先级链:RDRAND (x86_64) → detail::GetOsEntropyBytes → std::random_device → 时间戳回退
1342 [[nodiscard]]
1343 inline std::uint64_t RandomSeed()
1344 {
1345 std::uint64_t hw;
1346 if (detail::HardwareRand64(hw))
1347 return hw;
1348 if (detail::GetOsEntropyBytes(&hw, sizeof(hw)))
1349 return hw;
1350 std::random_device rd;
1351 try
1352 {
1353 return (static_cast<std::uint64_t>(rd()) << 32) | rd();
1354 }
1355 catch (...)
1356 {
1357 // 最终兜底:多维熵源(非密码学,仅保证 RandomSeed 永不抛异常,且防止 MSVC 15.6ms 时钟窗口下并发种子碰撞)
1358 const auto t1 = std::chrono::high_resolution_clock::now().time_since_epoch().count();
1359 const auto t2 = std::chrono::steady_clock::now().time_since_epoch().count();
1360 const auto threadId = std::hash<std::thread::id>{}(std::this_thread::get_id());
1361 static std::atomic<std::uint64_t> counter{0};
1362 std::uint64_t stackVar = 0;
1363 const std::uint64_t addr = reinterpret_cast<std::uint64_t>(&stackVar);
1364
1365 const std::uint64_t rawSeed = static_cast<std::uint64_t>(t1) ^ static_cast<std::uint64_t>(t2)
1366 ^ threadId ^ addr ^ counter.fetch_add(1, std::memory_order_relaxed);
1367 SplitMix64 sm{ rawSeed };
1368 return sm();
1369 }
1370 }
1371
1372 // 默认线程局部引擎,使用 RandomSeed() 播种(含 RDRAND → OS API → random_device → 时间戳回退链)
1373 [[nodiscard]]
1375 {
1376 thread_local Xoshiro256StarStar engine{ RandomSeed() };
1377 return engine;
1378 }
1379
1381 inline void ResetThreadLocalEngine()
1382 {
1384 }
1385
1388
1393 inline void SecureRandomBytes(void* buf, std::size_t n)
1394 {
1395 if (n == 0) return;
1396 if (!detail::GetOsEntropyBytes(buf, n))
1397 throw std::runtime_error("SecureRandomBytes: OS entropy source failed");
1398 }
1399
1402 [[nodiscard]]
1403 inline std::uint64_t SecureSeed()
1404 {
1405 std::uint64_t seed;
1406 SecureRandomBytes(&seed, sizeof(seed));
1407 return seed;
1408 }
1409
1413 [[nodiscard]]
1414 inline bool IsOsCryptoEntropyAvailable() noexcept
1415 {
1417 }
1418
1420 //
1421 // ChaCha20 (RFC 8439) — CSPRNG 引擎实现
1422 //
1423 // 状态矩阵布局(16 × uint32,常数省略存于 m_state[0..11]):
1424 // 0 1 2 3 "expa" "nd 3" "2-by" "te k" ← 常数(generateBlock 时补齐)
1425 // 4 5 6 7 key[0] key[1] key[2] key[3] ← m_state[0..3]
1426 // 8 9 10 11 key[4] key[5] key[6] key[7] ← m_state[4..7]
1427 // 12 13 14 15 ctr nonce[0] nonce[1] nonce[2]← m_state[8..11]
1428 //
1429 // 生成流程:operator() → reseedIfNecessary → (缓存耗尽时)generateBlock → 取 8 字节
1430 //
1431
1432 inline ChaCha20::ChaCha20(ChaCha20&& other) noexcept
1433 : m_state(other.m_state),
1434 m_buffer(other.m_buffer),
1435 m_bufferPos(other.m_bufferPos),
1436 m_bytesSinceReseed(other.m_bytesSinceReseed),
1437 m_autoReseed(other.m_autoReseed)
1438 {
1439 detail::SecureWipe(other.m_state.data(), sizeof(other.m_state));
1440 detail::SecureWipe(other.m_buffer.data(), sizeof(other.m_buffer));
1441 other.reseed();
1442 }
1443
1444 inline ChaCha20& ChaCha20::operator=(ChaCha20&& other) noexcept
1445 {
1446 if (this != &other)
1447 {
1448 detail::SecureWipe(m_state.data(), sizeof(m_state));
1449 detail::SecureWipe(m_buffer.data(), sizeof(m_buffer));
1450
1451 m_state = other.m_state;
1452 m_buffer = other.m_buffer;
1453 m_bufferPos = other.m_bufferPos;
1454 m_bytesSinceReseed = other.m_bytesSinceReseed;
1455 m_autoReseed = other.m_autoReseed;
1456
1457 detail::SecureWipe(other.m_state.data(), sizeof(other.m_state));
1458 detail::SecureWipe(other.m_buffer.data(), sizeof(other.m_buffer));
1459 other.reseed();
1460 }
1461 return *this;
1462 }
1463
1464 inline ChaCha20::~ChaCha20() noexcept
1465 {
1466 detail::SecureWipe(m_state.data(), sizeof(m_state));
1467 detail::SecureWipe(m_buffer.data(), sizeof(m_buffer));
1468 }
1469
1470 // 构造方式 1:从 OS 熵自动播种(密码学安全,默认)
1471 inline ChaCha20::ChaCha20()
1472 : m_state{}, m_buffer{}, m_bufferPos(64), m_bytesSinceReseed(0), m_autoReseed(true)
1473 {
1474 reseed(); // 从 OS 熵获取 key + nonce,重置 counter
1475 }
1476
1477 // 构造方式 2:显式种子(仅测试/复现,非密码学安全)
1478 // 用 SplitMix64 将 64-bit 种子扩展为 32 字节 key + 12 字节 nonce
1479 inline ChaCha20::ChaCha20(const std::uint64_t seed)
1480 : m_state{}, m_buffer{}, m_bufferPos(64), m_bytesSinceReseed(0), m_autoReseed(false)
1481 {
1482 SplitMix64 sm{ seed };
1483 // key: 前 4 次 SplitMix64 输出,每次 8 字节按小端序拆为 2 个 uint32
1484 for (int i = 0; i < 4; ++i)
1485 {
1486 const std::uint64_t v = sm();
1487 m_state[i * 2] = static_cast<std::uint32_t>(v);
1488 m_state[i * 2 + 1] = static_cast<std::uint32_t>(v >> 32);
1489 }
1490 // nonce: 第 5 次输出(8 字节)+ 第 6 次输出低 4 字节(丢弃高 4 字节)
1491 {
1492 const std::uint64_t v5 = sm();
1493 m_state[9] = static_cast<std::uint32_t>(v5);
1494 m_state[10] = static_cast<std::uint32_t>(v5 >> 32);
1495 }
1496 m_state[11] = static_cast<std::uint32_t>(sm());
1497 m_state[8] = 0; // counter 初值 = 0
1498 }
1499
1500 // 构造方式 3:直接指定 key + nonce + counter
1501 inline ChaCha20::ChaCha20(const std::uint8_t* key, std::size_t keyLen,
1502 const std::uint8_t* nonce, std::size_t nonceLen,
1503 const std::uint32_t counter)
1504 : m_state{}, m_buffer{}, m_bufferPos(64), m_bytesSinceReseed(0), m_autoReseed(false)
1505 {
1506 if (keyLen != 32)
1507 throw std::invalid_argument("ChaCha20: key must be 32 bytes");
1508 if (nonceLen != 12)
1509 throw std::invalid_argument("ChaCha20: nonce must be 12 bytes");
1510 // key → m_state[0..7](小端序)
1511 for (int i = 0; i < 8; ++i)
1512 {
1513 m_state[i] = static_cast<std::uint32_t>(key[i * 4])
1514 | (static_cast<std::uint32_t>(key[i * 4 + 1]) << 8)
1515 | (static_cast<std::uint32_t>(key[i * 4 + 2]) << 16)
1516 | (static_cast<std::uint32_t>(key[i * 4 + 3]) << 24);
1517 }
1518 // nonce → m_state[9..11](小端序)
1519 for (int i = 0; i < 3; ++i)
1520 {
1521 m_state[9 + i] = static_cast<std::uint32_t>(nonce[i * 4])
1522 | (static_cast<std::uint32_t>(nonce[i * 4 + 1]) << 8)
1523 | (static_cast<std::uint32_t>(nonce[i * 4 + 2]) << 16)
1524 | (static_cast<std::uint32_t>(nonce[i * 4 + 3]) << 24);
1525 }
1526 m_state[8] = counter; // counter
1527 }
1528
1529 // 生成一个 ChaCha20 block(64 字节)填充 m_buffer
1530 inline void ChaCha20::generateBlock()
1531 {
1532 if (m_state[8] == 0xFFFFFFFFU)
1533 {
1534 throw std::overflow_error("ChaCha20: 32-bit block counter overflow");
1535 }
1536
1537 // 构造完整 16-word 状态:常数 + key + counter + nonce
1538 std::array<std::uint32_t, 16> state{};
1539 state[0] = detail::ChaCha20Constants[0];
1540 state[1] = detail::ChaCha20Constants[1];
1541 state[2] = detail::ChaCha20Constants[2];
1542 state[3] = detail::ChaCha20Constants[3];
1543 for (int i = 0; i < 8; ++i) state[4 + i] = m_state[i]; // key
1544 state[12] = m_state[8]; // counter
1545 state[13] = m_state[9]; // nonce[0]
1546 state[14] = m_state[10]; // nonce[1]
1547 state[15] = m_state[11]; // nonce[2]
1548
1549 std::array<std::uint32_t, 16> working = state;
1550
1551 // 20 轮 = 10 次 double-round(列轮 + 对角轮)
1552 for (int i = 0; i < 10; ++i)
1553 {
1554 // 列轮 QR 顺序:(0,4,8,12) (1,5,9,13) (2,6,10,14) (3,7,11,15)
1555 detail::ChaCha20QuarterRound(working[0], working[4], working[8], working[12]);
1556 detail::ChaCha20QuarterRound(working[1], working[5], working[9], working[13]);
1557 detail::ChaCha20QuarterRound(working[2], working[6], working[10], working[14]);
1558 detail::ChaCha20QuarterRound(working[3], working[7], working[11], working[15]);
1559 // 对角轮 QR 顺序:(0,5,10,15) (1,6,11,12) (2,7,8,13) (3,4,9,14)
1560 detail::ChaCha20QuarterRound(working[0], working[5], working[10], working[15]);
1561 detail::ChaCha20QuarterRound(working[1], working[6], working[11], working[12]);
1562 detail::ChaCha20QuarterRound(working[2], working[7], working[8], working[13]);
1563 detail::ChaCha20QuarterRound(working[3], working[4], working[9], working[14]);
1564 }
1565
1566 // 加初始状态后按小端序输出 64 字节到 m_buffer
1567 for (int i = 0; i < 16; ++i)
1568 {
1569 const std::uint32_t v = working[i] + state[i];
1570 m_buffer[i * 4 + 0] = static_cast<std::uint8_t>(v);
1571 m_buffer[i * 4 + 1] = static_cast<std::uint8_t>(v >> 8);
1572 m_buffer[i * 4 + 2] = static_cast<std::uint8_t>(v >> 16);
1573 m_buffer[i * 4 + 3] = static_cast<std::uint8_t>(v >> 24);
1574 }
1575
1576 ++m_state[8]; // 递增 counter(2^20 字节阈值远早于 2^32 回绕,自动 reseed 防止复用)
1577 m_bufferPos = 0;
1578 }
1579
1580 // 自上次 reseed 以来输出字节数达到阈值时自动 reseed(前向安全)
1581 inline void ChaCha20::reseedIfNecessary()
1582 {
1583 if (m_autoReseed && m_bytesSinceReseed >= detail::ChaCha20ReseedThreshold)
1584 reseed();
1585 }
1586
1587 // 从 OS 熵重新播种:32 字节新 key + 12 字节新 nonce,重置 counter=0、缓存标记耗尽
1588 inline void ChaCha20::reseed()
1589 {
1590 std::array<std::uint8_t, 44> seed; // 32(key) + 12(nonce)
1591 SecureRandomBytes(seed.data(), seed.size());
1592 // key → m_state[0..7](小端序)
1593 for (int i = 0; i < 8; ++i)
1594 {
1595 m_state[i] = static_cast<std::uint32_t>(seed[i * 4])
1596 | (static_cast<std::uint32_t>(seed[i * 4 + 1]) << 8)
1597 | (static_cast<std::uint32_t>(seed[i * 4 + 2]) << 16)
1598 | (static_cast<std::uint32_t>(seed[i * 4 + 3]) << 24);
1599 }
1600 // nonce → m_state[9..11](小端序)
1601 for (int i = 0; i < 3; ++i)
1602 {
1603 m_state[9 + i] = static_cast<std::uint32_t>(seed[32 + i * 4])
1604 | (static_cast<std::uint32_t>(seed[32 + i * 4 + 1]) << 8)
1605 | (static_cast<std::uint32_t>(seed[32 + i * 4 + 2]) << 16)
1606 | (static_cast<std::uint32_t>(seed[32 + i * 4 + 3]) << 24);
1607 }
1608 m_state[8] = 0; // counter 重置
1609 m_bufferPos = 64; // 强制下次 operator() 触发新 block
1610 m_bytesSinceReseed = 0;
1611 detail::SecureWipe(seed.data(), seed.size()); // 擦除栈上密钥材料
1612 detail::SecureWipe(m_buffer.data(), m_buffer.size()); // 擦除旧 keystream
1613 }
1614
1615 // 生成一个 64-bit 随机数(从缓存取 8 字节,缓存耗尽时生成新 block)
1616 inline ChaCha20::result_type ChaCha20::operator()()
1617 {
1618 reseedIfNecessary();
1619 if (m_bufferPos == 64)
1620 generateBlock();
1621 // 从缓存取 8 字节,小端序组装为 uint64_t
1622 std::uint64_t result = 0;
1623 for (int i = 0; i < 8; ++i)
1624 result |= static_cast<std::uint64_t>(m_buffer[m_bufferPos + i]) << (8 * i);
1625 m_bufferPos += 8;
1626 m_bytesSinceReseed += 8;
1627 return result;
1628 }
1629
1630 inline void ChaCha20::discard(const unsigned long long n)
1631 {
1632 for (unsigned long long i = 0; i < n; ++i) operator()();
1633 }
1634
1635 // 重置默认引擎的种子(用于测试复现)
1636 inline void Reseed(std::uint64_t seed)
1637 {
1638 DefaultEngine() = Xoshiro256StarStar{ seed };
1639 }
1640
1641 // 重置为真随机种子
1642 inline void ReseedRandom()
1643 {
1644 DefaultEngine() = Xoshiro256StarStar{ RandomSeed() };
1645 }
1646
1649
1654 template <class T = int, std::enable_if_t<std::is_integral_v<T>>* = nullptr>
1655 [[nodiscard]]
1656 inline T RandInt(T min, T max)
1657 {
1658 return RandInt(DefaultEngine(), min, max);
1659 }
1660
1664 template <class T = int, std::enable_if_t<std::is_integral_v<T>>* = nullptr>
1665 [[nodiscard]]
1666 inline T RandInt(T max)
1667 {
1668 assert(max >= T{0});
1669 return RandInt<T>(T{0}, max);
1670 }
1671
1676 template <class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
1677 [[nodiscard]]
1678 inline T RandReal(T min = T{0}, T max = T{1})
1679 {
1680 return RandReal(DefaultEngine(), min, max);
1681 }
1682
1686 template <class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
1687 [[nodiscard]]
1688 inline T RandCanonical() noexcept
1689 {
1691 }
1692
1694 [[nodiscard]]
1695 inline double RandCanonicalDouble() noexcept
1696 {
1697 return RandCanonical<double>();
1698 }
1699
1701 [[nodiscard]]
1702 inline float RandCanonicalFloat() noexcept
1703 {
1704 return RandCanonical<float>();
1705 }
1706
1710 [[nodiscard]]
1711 inline bool RandBool(double p = 0.5)
1712 {
1713 assert(std::isfinite(p) && p >= 0.0 && p <= 1.0);
1714 std::bernoulli_distribution dist(p);
1715 return dist(DefaultEngine());
1716 }
1717
1722 template <class Engine>
1723 [[nodiscard]]
1724 inline bool RandBool(Engine& engine, double p = 0.5)
1725 {
1726 assert(std::isfinite(p) && p >= 0.0 && p <= 1.0);
1727 std::bernoulli_distribution dist(p);
1728 return dist(engine);
1729 }
1730
1734 [[nodiscard]]
1735 inline bool RandBernoulli(double p = 0.5)
1736 {
1737 assert(p >= 0.0 && p <= 1.0);
1738 return RandBool(p);
1739 }
1740
1745 template <class Engine>
1746 [[nodiscard]]
1747 inline bool RandBernoulli(Engine& engine, double p = 0.5)
1748 {
1749 assert(p >= 0.0 && p <= 1.0);
1750 return RandBool(engine, p);
1751 }
1752
1758 template <class CharT,
1759 std::enable_if_t<detail::is_character_v<CharT>>* = nullptr>
1760 [[nodiscard]]
1761 inline CharT RandChar(CharT min, CharT max)
1762 {
1763 assert(min <= max);
1764 using IntT = std::int64_t;
1765 std::uniform_int_distribution<IntT> dist(
1766 static_cast<IntT>(min), static_cast<IntT>(max));
1767 return static_cast<CharT>(dist(DefaultEngine()));
1768 }
1769
1773 template <class CharT,
1774 std::enable_if_t<detail::is_character_v<CharT>>* = nullptr>
1775 [[nodiscard]]
1776 inline CharT RandChar(CharT max)
1777 {
1778 return RandChar<CharT>(CharT{}, max);
1779 }
1780
1786 template <class CharT, class Engine,
1787 std::enable_if_t<detail::is_character_v<CharT>>* = nullptr>
1788 [[nodiscard]]
1789 inline CharT RandChar(Engine& engine, CharT min, CharT max)
1790 {
1791 assert(min <= max);
1792 using IntT = std::int64_t;
1793 std::uniform_int_distribution<IntT> dist(
1794 static_cast<IntT>(min), static_cast<IntT>(max));
1795 return static_cast<CharT>(dist(engine));
1796 }
1797
1802 template <class CharT, class Engine,
1803 std::enable_if_t<detail::is_character_v<CharT>>* = nullptr>
1804 [[nodiscard]]
1805 inline CharT RandChar(Engine& engine, CharT max)
1806 {
1807 return RandChar<CharT>(engine, CharT{}, max);
1808 }
1809
1811 //
1812 // RandChar / RandString 预设字符集
1813 //
1814 // 提供常用字符集枚举,避免手写 ASCII 范围或字符串。
1815 //
1816
1817 // 预设字符集枚举
1818 enum class CharSet
1819 {
1820 Alphanumeric, // [A-Za-z0-9] 62 个
1821 Alpha, // [A-Za-z] 52 个
1822 Lower, // [a-z] 26 个
1823 Upper, // [A-Z] 26 个
1824 Digit, // [0-9] 10 个
1825 Hex, // [0-9a-f] 16 个
1826 Printable, // [!-~] 94 个可打印 ASCII
1827 Base64, // [A-Za-z0-9+/] 64 个(RFC 4648 §4 标准变体)
1828 Base64UrlSafe, // [A-Za-z0-9-_] 64 个(RFC 4648 §5 URL-safe 变体)
1829 };
1830
1831 namespace detail
1832 {
1833 // RandSample 分支选择阈值:n·K < size 时用 hash-set(实测交叉点 n≈N/127,K=64 留 2× 裕度)
1834 inline constexpr std::uint64_t HashSetThresholdK = 64;
1835
1836 // 返回预设字符集的字符串视图(零拷贝,指向静态存储)
1837 [[nodiscard]]
1838 inline std::string_view CharSetString(CharSet cs) noexcept
1839 {
1840 switch (cs)
1841 {
1842 case CharSet::Alphanumeric:
1843 return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
1844 case CharSet::Alpha:
1845 return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
1846 case CharSet::Lower:
1847 return "abcdefghijklmnopqrstuvwxyz";
1848 case CharSet::Upper:
1849 return "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1850 case CharSet::Digit:
1851 return "0123456789";
1852 case CharSet::Hex:
1853 return "0123456789abcdef";
1854 case CharSet::Printable:
1855 return "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
1856 case CharSet::Base64:
1857 return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1858 case CharSet::Base64UrlSafe:
1859 return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
1860 }
1861 return "";
1862 }
1863 }
1864
1869 [[nodiscard]]
1870 inline char RandChar(CharSet cs)
1871 {
1872 const auto charset = detail::CharSetString(cs);
1873 if (charset.empty())
1874 throw std::invalid_argument("RandChar: charset is empty");
1875 auto& rng = DefaultEngine();
1876 std::uniform_int_distribution<std::size_t> dist(0, charset.size() - 1);
1877 return charset[dist(rng)];
1878 }
1879
1884 template <class Engine>
1885 [[nodiscard]]
1886 inline char RandChar(Engine& engine, CharSet cs)
1887 {
1888 const auto charset = detail::CharSetString(cs);
1889 if (charset.empty())
1890 throw std::invalid_argument("RandChar: charset is empty");
1891 std::uniform_int_distribution<std::size_t> dist(0, charset.size() - 1);
1892 return charset[dist(engine)];
1893 }
1894
1897
1902 template <class Container,
1903 std::enable_if_t<detail::is_random_access_container_v<Container>>* = nullptr>
1904 [[nodiscard]]
1905 inline decltype(auto) RandElement(Container& c)
1906 {
1907 if (std::empty(c))
1908 throw std::invalid_argument("RandElement: empty container");
1909 return c[RandInt<std::size_t>(static_cast<std::size_t>(std::size(c) - 1))];
1910 }
1911
1916 template <class Container,
1917 std::enable_if_t<detail::is_random_access_container_v<std::decay_t<Container>>>* = nullptr>
1918 [[nodiscard]]
1919 inline typename std::iterator_traits<decltype(std::begin(std::declval<Container&>()))>::value_type RandElement(Container&& c)
1920 {
1921 if (std::empty(c))
1922 throw std::invalid_argument("RandElement: empty container");
1923 return c[RandInt<std::size_t>(static_cast<std::size_t>(std::size(c) - 1))];
1924 }
1925
1931 template <class It,
1932 std::enable_if_t<detail::is_random_access_iterator_v<It>>* = nullptr>
1933 [[nodiscard]]
1934 inline It RandElement(It first, It last)
1935 {
1936 using Diff = typename std::iterator_traits<It>::difference_type;
1937 const Diff n = std::distance(first, last);
1938 if (n <= 0)
1939 throw std::invalid_argument("RandElement: empty range");
1940 return std::next(first, RandInt<Diff>(Diff{0}, n - 1));
1941 }
1942
1948 template <class It,
1949 std::enable_if_t<detail::is_input_iterator_v<It>
1950 && !detail::is_random_access_iterator_v<It>>* = nullptr>
1951 [[nodiscard]]
1952 inline typename std::iterator_traits<It>::value_type RandElement(It first, It last)
1953 {
1954 if (first == last)
1955 throw std::invalid_argument("RandElement: empty range");
1956 typename std::iterator_traits<It>::value_type selected = *first;
1957 ++first;
1958 for (typename std::iterator_traits<It>::difference_type i = 1;
1959 first != last; ++first, ++i)
1960 {
1961 if (RandInt<typename std::iterator_traits<It>::difference_type>(0, i) == 0)
1962 selected = *first;
1963 }
1964 return selected;
1965 }
1966
1972 template <class It, class Engine,
1973 std::enable_if_t<detail::is_random_access_iterator_v<It>>* = nullptr>
1974 [[nodiscard]]
1975 inline It RandElement(Engine& engine, It first, It last)
1976 {
1977 using Diff = typename std::iterator_traits<It>::difference_type;
1978 const Diff n = std::distance(first, last);
1979 if (n <= 0)
1980 throw std::invalid_argument("RandElement: empty range");
1981 return std::next(first, RandInt<Diff>(engine, Diff{0}, n - 1));
1982 }
1983
1989 template <class It, class Engine,
1990 std::enable_if_t<detail::is_input_iterator_v<It>
1991 && !detail::is_random_access_iterator_v<It>>* = nullptr>
1992 [[nodiscard]]
1993 inline typename std::iterator_traits<It>::value_type RandElement(Engine& engine, It first, It last)
1994 {
1995 if (first == last)
1996 throw std::invalid_argument("RandElement: empty range");
1997 typename std::iterator_traits<It>::value_type selected = *first;
1998 ++first;
1999 for (typename std::iterator_traits<It>::difference_type i = 1;
2000 first != last; ++first, ++i)
2001 {
2002 if (RandInt<typename std::iterator_traits<It>::difference_type>(
2003 engine, typename std::iterator_traits<It>::difference_type{0}, i) == 0)
2004 selected = *first;
2005 }
2006 return selected;
2007 }
2008
2009
2012
2017 template <class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
2018 [[nodiscard]]
2019 inline T RandNormal(T mean = T{0}, T stddev = T{1})
2020 {
2021 if (!std::isfinite(mean) || !std::isfinite(stddev) || stddev <= T{0})
2022 throw std::invalid_argument("RandNormal: invalid mean or stddev");
2023 std::normal_distribution<T> dist(mean, stddev);
2024 return dist(DefaultEngine());
2025 }
2026
2032 template <class Engine, class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
2033 [[nodiscard]]
2034 inline T RandNormal(Engine& engine, T mean = T{0}, T stddev = T{1})
2035 {
2036 if (!std::isfinite(mean) || !std::isfinite(stddev) || stddev <= T{0})
2037 throw std::invalid_argument("RandNormal: invalid mean or stddev");
2038 std::normal_distribution<T> dist(mean, stddev);
2039 return dist(engine);
2040 }
2041
2044 template <class Container,
2045 std::enable_if_t<detail::is_random_access_container_v<Container>>* = nullptr>
2046 inline void RandShuffle(Container&& c)
2047 {
2048 std::shuffle(c.begin(), c.end(), DefaultEngine());
2049 }
2050
2058 template <class It, class T,
2059 std::enable_if_t<detail::is_rand_fillable_v<It, T>>* = nullptr>
2060 inline void RandFill(It first, It last, T min, T max)
2061 {
2062 assert(min <= max);
2063 auto& rng = DefaultEngine();
2064 if constexpr (std::is_integral_v<T>)
2065 {
2066 std::uniform_int_distribution<T> dist(min, max);
2067 for (; first != last; ++first) *first = dist(rng);
2068 }
2069 else
2070 {
2071 std::uniform_real_distribution<T> dist(min, max);
2072 for (; first != last; ++first) *first = dist(rng);
2073 }
2074 }
2075
2082 template <class It, class T, class Engine,
2083 std::enable_if_t<detail::is_rand_fillable_v<It, T>>* = nullptr>
2084 inline void RandFill(Engine& engine, It first, It last, T min, T max)
2085 {
2086 assert(min <= max);
2087 if constexpr (std::is_integral_v<T>)
2088 {
2089 std::uniform_int_distribution<T> dist(min, max);
2090 for (; first != last; ++first) *first = dist(engine);
2091 }
2092 else
2093 {
2094 std::uniform_real_distribution<T> dist(min, max);
2095 for (; first != last; ++first) *first = dist(engine);
2096 }
2097 }
2098
2104 template <class T,
2105 std::enable_if_t<std::is_integral_v<T>>* = nullptr>
2106 [[nodiscard]]
2107 inline std::vector<T> RandVector(T min, T max, std::size_t n)
2108 {
2109 assert(min <= max);
2110 std::vector<T> v;
2111 v.reserve(n);
2112 auto& rng = DefaultEngine();
2113 std::uniform_int_distribution<T> dist(min, max);
2114 for (std::size_t i = 0; i < n; ++i)
2115 v.push_back(dist(rng));
2116 return v;
2117 }
2118
2124 template <class T,
2125 std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
2126 [[nodiscard]]
2127 inline std::vector<T> RandVector(T min, T max, std::size_t n)
2128 {
2129 assert(min <= max);
2130 std::vector<T> v;
2131 v.reserve(n);
2132 auto& rng = DefaultEngine();
2133 std::uniform_real_distribution<T> dist(min, max);
2134 for (std::size_t i = 0; i < n; ++i)
2135 v.push_back(dist(rng));
2136 return v;
2137 }
2138
2145 template <class T, class Engine,
2146 std::enable_if_t<std::is_integral_v<T>>* = nullptr>
2147 [[nodiscard]]
2148 inline std::vector<T> RandVector(Engine& engine, T min, T max, std::size_t n)
2149 {
2150 assert(min <= max);
2151 std::vector<T> v;
2152 v.reserve(n);
2153 std::uniform_int_distribution<T> dist(min, max);
2154 for (std::size_t i = 0; i < n; ++i)
2155 v.push_back(dist(engine));
2156 return v;
2157 }
2158
2165 template <class T, class Engine,
2166 std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
2167 [[nodiscard]]
2168 inline std::vector<T> RandVector(Engine& engine, T min, T max, std::size_t n)
2169 {
2170 assert(min <= max);
2171 std::vector<T> v;
2172 v.reserve(n);
2173 std::uniform_real_distribution<T> dist(min, max);
2174 for (std::size_t i = 0; i < n; ++i)
2175 v.push_back(dist(engine));
2176 return v;
2177 }
2178
2182 template <class WeightContainer>
2183 [[nodiscard]]
2184 inline typename WeightContainer::size_type RandWeighted(const WeightContainer& weights)
2185 {
2186 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; }));
2187 using Size = typename WeightContainer::size_type;
2188 std::discrete_distribution<Size> dist(weights.begin(), weights.end());
2189 return dist(DefaultEngine());
2190 }
2191
2196 template <class Engine, class WeightContainer>
2197 [[nodiscard]]
2198 inline typename WeightContainer::size_type RandWeighted(Engine& engine, const WeightContainer& weights)
2199 {
2200 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; }));
2201 using Size = typename WeightContainer::size_type;
2202 std::discrete_distribution<Size> dist(weights.begin(), weights.end());
2203 return dist(engine);
2204 }
2205
2209 template <class IntType>
2210 [[nodiscard]]
2211 inline IntType RandWeighted(std::discrete_distribution<IntType>& dist)
2212 {
2213 return dist(DefaultEngine());
2214 }
2215
2220 template <class Engine, class IntType>
2221 [[nodiscard]]
2222 inline IntType RandWeighted(Engine& engine, std::discrete_distribution<IntType>& dist)
2223 {
2224 return dist(engine);
2225 }
2226
2232 template <class T, class Engine, std::enable_if_t<std::is_integral_v<T>>* = nullptr>
2233 [[nodiscard]]
2234 inline T RandInt(Engine& engine, T min, T max)
2235 {
2236 assert(min <= max);
2237 using DistType = std::conditional_t<(sizeof(T) < sizeof(short)),
2238 std::conditional_t<std::is_signed_v<T>, int, unsigned int>, T>;
2239 std::uniform_int_distribution<DistType> dist(static_cast<DistType>(min), static_cast<DistType>(max));
2240 return static_cast<T>(dist(engine));
2241 }
2242
2247 template <typename T = double, class Engine,
2248 typename std::enable_if_t<std::is_floating_point_v<T>, int> = 0>
2249 [[nodiscard]] inline constexpr T RandCanonical(Engine& engine) noexcept
2250 {
2251 using ResultType = typename Engine::result_type;
2252 constexpr std::size_t Bits = sizeof(ResultType) * 8;
2253
2254 if constexpr (std::is_same_v<T, double>)
2255 {
2256 if constexpr (Bits >= 64)
2257 {
2258 const std::uint64_t r = static_cast<std::uint64_t>(engine());
2259 return static_cast<double>(r >> 11) * 0x1.0p-53;
2260 }
2261 else
2262 {
2263 const std::uint64_t high = static_cast<std::uint64_t>(engine());
2264 const std::uint64_t low = static_cast<std::uint64_t>(engine());
2265 const std::uint64_t r = (high << 32) | low;
2266 return static_cast<double>(r >> 11) * 0x1.0p-53;
2267 }
2268 }
2269 else if constexpr (std::is_same_v<T, float>)
2270 {
2271 if constexpr (Bits >= 64)
2272 {
2273 const std::uint64_t r = static_cast<std::uint64_t>(engine());
2274 return static_cast<float>(r >> 40) * 0x1.0p-24f;
2275 }
2276 else
2277 {
2278 const std::uint32_t r = static_cast<std::uint32_t>(engine());
2279 return static_cast<float>(r >> 8) * 0x1.0p-24f;
2280 }
2281 }
2282 else
2283 {
2284 return std::generate_canonical<T, std::numeric_limits<T>::digits>(engine);
2285 }
2286 }
2287
2293 template <class T = double, class Engine, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
2294 [[nodiscard]]
2295 inline T RandReal(Engine& engine, T min = T{0}, T max = T{1})
2296 {
2297 assert(std::isfinite(min) && std::isfinite(max) && min <= max);
2298 if (min == T{0} && max == T{1})
2299 {
2300 return RandCanonical<T>(engine);
2301 }
2302 std::uniform_real_distribution<T> dist(min, max);
2303 T val = dist(engine);
2304 if (val >= max) val = std::nextafter(max, min);
2305 return val;
2306 }
2307
2309 //
2310 // 扩展便捷 API
2311 //
2312
2317 template <class Container,
2318 std::enable_if_t<detail::is_random_access_container_v<Container>>* = nullptr>
2319 [[nodiscard]]
2320 inline auto RandSample(const Container& c, std::size_t n)
2321 {
2322 using T = typename std::iterator_traits<decltype(std::begin(c))>::value_type;
2323 using Size = std::size_t;
2324 std::vector<T> pool(std::begin(c), std::end(c));
2325 const Size size = pool.size();
2326 if (n >= size) return pool;
2327 auto& rng = DefaultEngine();
2328 for (Size i = 0; i < n; ++i)
2329 {
2330 std::uniform_int_distribution<Size> dist(i, size - 1);
2331 const Size j = dist(rng);
2332 auto tmp = std::move(pool[i]);
2333 pool[i] = std::move(pool[j]);
2334 pool[j] = std::move(tmp);
2335 }
2336 pool.resize(n);
2337 return pool;
2338 }
2339
2340 // ============================================================
2341 // RandSample 迭代器版
2342 // 路径 1:随机访问迭代器 —— hash-set / 索引数组双分支
2343 // 路径 2:输入迭代器 —— reservoir sampling (Algorithm R, i+1 修复)
2344 // ============================================================
2345
2346 // 路径 1:随机访问迭代器(hash-set / 索引数组双分支)
2347 template <class It,
2348 std::enable_if_t<detail::is_random_access_iterator_v<It>>* = nullptr>
2349 [[nodiscard]]
2350 inline std::vector<typename std::iterator_traits<It>::value_type>
2351 RandSample(It first, It last, typename std::iterator_traits<It>::difference_type n)
2352 {
2353 using Diff = typename std::iterator_traits<It>::difference_type;
2354 using T = typename std::iterator_traits<It>::value_type;
2355 const Diff size = std::distance(first, last);
2356 if (n <= 0 || size <= 0)
2357 return {};
2358 if (n >= size)
2359 return std::vector<T>(first, last);
2360
2361 auto& rng = DefaultEngine();
2362
2363 // 分支选择:n·K < size 时 hash-set 内存优(O(n));否则索引数组常数优(O(N))
2364 const auto sizeU = static_cast<std::uint64_t>(size);
2365 // 线性阈值:n·K < size 时用 hash-set(实测交叉点 n≈N/127,K=64 留 2× 裕度)
2366 if (static_cast<std::uint64_t>(n) * detail::HashSetThresholdK < sizeU)
2367 {
2368 // hash-set 分支:O(n) 内存,O(n) 期望时间
2369 std::unordered_set<Diff> selected;
2370 selected.reserve(static_cast<std::size_t>(n));
2371 std::vector<T> result;
2372 result.reserve(static_cast<std::size_t>(n));
2373 while (result.size() < static_cast<std::size_t>(n))
2374 {
2375 std::uniform_int_distribution<Diff> dist(Diff{0}, static_cast<Diff>(sizeU - 1));
2376 const Diff idx = dist(rng);
2377 if (selected.insert(idx).second)
2378 result.push_back(first[idx]);
2379 }
2380 return result;
2381 }
2382
2383 // 索引数组分支:O(N) 内存,O(N) 时间,无碰撞
2384 std::vector<Diff> indices(static_cast<std::size_t>(size));
2385 for (Diff i = 0; i < size; ++i)
2386 indices[static_cast<std::size_t>(i)] = i;
2387
2388 // Fisher-Yates 前 n 步:j ∈ [i, size-1]
2389 for (Diff i = 0; i < n; ++i)
2390 {
2391 std::uniform_int_distribution<Diff> dist(i, static_cast<Diff>(size - 1));
2392 const Diff j = dist(rng);
2393 std::swap(indices[static_cast<std::size_t>(i)],
2394 indices[static_cast<std::size_t>(j)]);
2395 }
2396
2397 std::vector<T> result;
2398 result.reserve(static_cast<std::size_t>(n));
2399 for (Diff i = 0; i < n; ++i)
2400 result.push_back(first[indices[static_cast<std::size_t>(i)]]);
2401 return result;
2402 }
2403
2404 // 路径 2:输入迭代器(reservoir sampling, Algorithm R, i+1 修复)
2405 template <class It,
2406 std::enable_if_t<detail::is_input_iterator_v<It>
2407 && !detail::is_random_access_iterator_v<It>>* = nullptr>
2408 [[nodiscard]]
2409 inline std::vector<typename std::iterator_traits<It>::value_type>
2410 RandSample(It first, It last, typename std::iterator_traits<It>::difference_type n)
2411 {
2412 using Diff = typename std::iterator_traits<It>::difference_type;
2413 using T = typename std::iterator_traits<It>::value_type;
2414 if (n <= 0)
2415 return {};
2416
2417 std::vector<T> reservoir;
2418 reservoir.reserve(static_cast<std::size_t>(n));
2419
2420 // 填满蓄水池
2421 Diff i = 0;
2422 for (; i < n && first != last; ++i, ++first)
2423 reservoir.push_back(*first);
2424
2425 if (first == last)
2426 return reservoir; // 元素不足 n,返回全部
2427
2428 // Algorithm R:第 i 个元素(i >= n,0-indexed)以 n/(i+1) 概率替换蓄水池随机位置
2429 // 关键:j ∈ [0, i](闭区间),uniform_int_distribution(0, i) 正好是 [0, i] 闭区间
2430 auto& rng = DefaultEngine();
2431 for (; first != last; ++i, ++first)
2432 {
2433 std::uniform_int_distribution<Diff> dist(Diff{0}, i);
2434 const Diff j = dist(rng);
2435 if (j < n)
2436 reservoir[static_cast<std::size_t>(j)] = *first;
2437 }
2438 return reservoir;
2439 }
2440
2441 // 引擎重载 —— 随机访问迭代器
2442 template <class It, class Engine,
2443 std::enable_if_t<detail::is_random_access_iterator_v<It>>* = nullptr>
2444 [[nodiscard]]
2445 inline std::vector<typename std::iterator_traits<It>::value_type>
2446 RandSample(Engine& engine, It first, It last, typename std::iterator_traits<It>::difference_type n)
2447 {
2448 using Diff = typename std::iterator_traits<It>::difference_type;
2449 using T = typename std::iterator_traits<It>::value_type;
2450 const Diff size = std::distance(first, last);
2451 if (n <= 0 || size <= 0)
2452 return {};
2453 if (n >= size)
2454 return std::vector<T>(first, last);
2455
2456 const auto sizeU = static_cast<std::uint64_t>(size);
2457 // 线性阈值:n·K < size 时用 hash-set(实测交叉点 n≈N/127,K=64 留 2× 裕度)
2458 if (static_cast<std::uint64_t>(n) * detail::HashSetThresholdK < sizeU)
2459 {
2460 std::unordered_set<Diff> selected;
2461 selected.reserve(static_cast<std::size_t>(n));
2462 std::vector<T> result;
2463 result.reserve(static_cast<std::size_t>(n));
2464 while (result.size() < static_cast<std::size_t>(n))
2465 {
2466 std::uniform_int_distribution<Diff> dist(Diff{0}, static_cast<Diff>(sizeU - 1));
2467 const Diff idx = dist(engine);
2468 if (selected.insert(idx).second)
2469 result.push_back(first[idx]);
2470 }
2471 return result;
2472 }
2473
2474 std::vector<Diff> indices(static_cast<std::size_t>(size));
2475 for (Diff i = 0; i < size; ++i)
2476 indices[static_cast<std::size_t>(i)] = i;
2477
2478 for (Diff i = 0; i < n; ++i)
2479 {
2480 std::uniform_int_distribution<Diff> dist(i, static_cast<Diff>(size - 1));
2481 const Diff j = dist(engine);
2482 std::swap(indices[static_cast<std::size_t>(i)],
2483 indices[static_cast<std::size_t>(j)]);
2484 }
2485
2486 std::vector<T> result;
2487 result.reserve(static_cast<std::size_t>(n));
2488 for (Diff i = 0; i < n; ++i)
2489 result.push_back(first[indices[static_cast<std::size_t>(i)]]);
2490 return result;
2491 }
2492
2493 // 引擎重载 —— 输入迭代器(reservoir)
2494 template <class It, class Engine,
2495 std::enable_if_t<detail::is_input_iterator_v<It>
2496 && !detail::is_random_access_iterator_v<It>>* = nullptr>
2497 [[nodiscard]]
2498 inline std::vector<typename std::iterator_traits<It>::value_type>
2499 RandSample(Engine& engine, It first, It last, typename std::iterator_traits<It>::difference_type n)
2500 {
2501 using Diff = typename std::iterator_traits<It>::difference_type;
2502 using T = typename std::iterator_traits<It>::value_type;
2503 if (n <= 0)
2504 return {};
2505
2506 std::vector<T> reservoir;
2507 reservoir.reserve(static_cast<std::size_t>(n));
2508
2509 Diff i = 0;
2510 for (; i < n && first != last; ++i, ++first)
2511 reservoir.push_back(*first);
2512
2513 if (first == last)
2514 return reservoir;
2515
2516 // Algorithm R:j ∈ [0, i] 闭区间
2517 for (; first != last; ++i, ++first)
2518 {
2519 std::uniform_int_distribution<Diff> dist(Diff{0}, i);
2520 const Diff j = dist(engine);
2521 if (j < n)
2522 reservoir[static_cast<std::size_t>(j)] = *first;
2523 }
2524 return reservoir;
2525 }
2526
2530 [[nodiscard]]
2531 inline std::vector<std::size_t> RandPermutation(std::size_t n)
2532 {
2533 std::vector<std::size_t> perm(n);
2534 for (std::size_t i = 0; i < n; ++i) perm[i] = i;
2535 if (n < 2) return perm;
2536 auto& rng = DefaultEngine();
2537 for (std::size_t i = n - 1; i > 0; --i)
2538 {
2539 std::uniform_int_distribution<std::size_t> dist(0, i);
2540 const std::size_t j = dist(rng);
2541 auto tmp = perm[i];
2542 perm[i] = perm[j];
2543 perm[j] = tmp;
2544 }
2545 return perm;
2546 }
2547
2550
2556 [[nodiscard]]
2557 inline std::string RandString(std::size_t length, std::string_view charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
2558 {
2559 if (charset.empty())
2560 throw std::invalid_argument("RandString: charset is empty");
2561 std::string result(length, '\0');
2562 auto& rng = DefaultEngine();
2563 std::uniform_int_distribution<std::size_t> dist(0, charset.size() - 1);
2564 for (std::size_t i = 0; i < length; ++i)
2565 result[i] = charset[dist(rng)];
2566 return result;
2567 }
2568
2573 [[nodiscard]]
2574 inline std::string RandString(std::size_t n, CharSet cs)
2575 {
2576 return RandString(n, detail::CharSetString(cs));
2577 }
2578
2585 template <class Engine>
2586 [[nodiscard]]
2587 inline std::string RandString(Engine& engine, std::size_t n, std::string_view charset)
2588 {
2589 if (charset.empty())
2590 throw std::invalid_argument("RandString: charset is empty");
2591 std::string result(n, '\0');
2592 std::uniform_int_distribution<std::size_t> dist(0, charset.size() - 1);
2593 for (std::size_t i = 0; i < n; ++i)
2594 result[i] = charset[dist(engine)];
2595 return result;
2596 }
2597
2603 template <class Engine>
2604 [[nodiscard]]
2605 inline std::string RandString(Engine& engine, std::size_t n, CharSet cs)
2606 {
2607 return RandString(engine, n, detail::CharSetString(cs));
2608 }
2609
2613 template <class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
2614 [[nodiscard]]
2615 inline T RandExp(T lambda = T{1})
2616 {
2617 if (!std::isfinite(lambda) || lambda <= T{0})
2618 throw std::invalid_argument("RandExp: lambda must be positive");
2619 std::exponential_distribution<T> dist(lambda);
2620 return dist(DefaultEngine());
2621 }
2622
2627 template <class Engine, class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
2628 [[nodiscard]]
2629 inline T RandExp(Engine& engine, T lambda = T{1})
2630 {
2631 if (!std::isfinite(lambda) || lambda <= T{0})
2632 throw std::invalid_argument("RandExp: lambda must be positive");
2633 std::exponential_distribution<T> dist(lambda);
2634 return dist(engine);
2635 }
2636
2640 template <class T = int, std::enable_if_t<std::is_integral_v<T>>* = nullptr>
2641 [[nodiscard]]
2642 inline T RandPoisson(double mean = 1.0)
2643 {
2644 if (!std::isfinite(mean) || mean < 0.0)
2645 throw std::invalid_argument("RandPoisson: mean must be non-negative");
2646 if (mean == 0.0) return T{0};
2647 std::poisson_distribution<T> dist(mean);
2648 return dist(DefaultEngine());
2649 }
2650
2655 template <class Engine, class T = int, std::enable_if_t<std::is_integral_v<T>>* = nullptr>
2656 [[nodiscard]]
2657 inline T RandPoisson(Engine& engine, double mean = 1.0)
2658 {
2659 if (!std::isfinite(mean) || mean < 0.0)
2660 throw std::invalid_argument("RandPoisson: mean must be non-negative");
2661 if (mean == 0.0) return T{0};
2662 std::poisson_distribution<T> dist(mean);
2663 return dist(engine);
2664 }
2665
2670 template <class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
2671 [[nodiscard]]
2672 inline T RandGamma(T alpha = T{1}, T beta = T{1})
2673 {
2674 if (!std::isfinite(alpha) || !std::isfinite(beta) || alpha <= T{0} || beta <= T{0})
2675 throw std::invalid_argument("RandGamma: alpha and beta must be positive");
2676 std::gamma_distribution<T> dist(alpha, beta);
2677 return dist(DefaultEngine());
2678 }
2679
2685 template <class Engine, class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
2686 [[nodiscard]]
2687 inline T RandGamma(Engine& engine, T alpha = T{1}, T beta = T{1})
2688 {
2689 if (!std::isfinite(alpha) || !std::isfinite(beta) || alpha <= T{0} || beta <= T{0})
2690 throw std::invalid_argument("RandGamma: alpha and beta must be positive");
2691 std::gamma_distribution<T> dist(alpha, beta);
2692 return dist(engine);
2693 }
2694
2699 template <class T = int, std::enable_if_t<std::is_integral_v<T>>* = nullptr>
2700 [[nodiscard]]
2701 inline T RandBinomial(T t = 1, double p = 0.5)
2702 {
2703 if (t < 0 || !std::isfinite(p) || p < 0.0 || p > 1.0)
2704 throw std::invalid_argument("RandBinomial: invalid t or p");
2705 std::binomial_distribution<T> dist(t, p);
2706 return dist(DefaultEngine());
2707 }
2708
2714 template <class Engine, class T = int, std::enable_if_t<std::is_integral_v<T>>* = nullptr>
2715 [[nodiscard]]
2716 inline T RandBinomial(Engine& engine, T t = 1, double p = 0.5)
2717 {
2718 if (t < 0 || !std::isfinite(p) || p < 0.0 || p > 1.0)
2719 throw std::invalid_argument("RandBinomial: invalid t or p");
2720 std::binomial_distribution<T> dist(t, p);
2721 return dist(engine);
2722 }
2723
2728 template <class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
2729 [[nodiscard]]
2730 inline T RandLogNormal(T mean = T{0}, T stddev = T{1})
2731 {
2732 if (!std::isfinite(mean) || !std::isfinite(stddev) || stddev <= T{0})
2733 throw std::invalid_argument("RandLogNormal: invalid mean or stddev");
2734 std::lognormal_distribution<T> dist(mean, stddev);
2735 return dist(DefaultEngine());
2736 }
2737
2743 template <class Engine, class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
2744 [[nodiscard]]
2745 inline T RandLogNormal(Engine& engine, T mean = T{0}, T stddev = T{1})
2746 {
2747 if (!std::isfinite(mean) || !std::isfinite(stddev) || stddev <= T{0})
2748 throw std::invalid_argument("RandLogNormal: invalid mean or stddev");
2749 std::lognormal_distribution<T> dist(mean, stddev);
2750 return dist(engine);
2751 }
2752
2756 template <class T = int, std::enable_if_t<std::is_integral_v<T>>* = nullptr>
2757 [[nodiscard]]
2758 inline T RandGeometric(double p = 0.5)
2759 {
2760 if (!std::isfinite(p) || p <= 0.0 || p > 1.0)
2761 throw std::invalid_argument("RandGeometric: p must be in (0, 1]");
2762 std::geometric_distribution<T> dist(p);
2763 return dist(DefaultEngine());
2764 }
2765
2770 template <class Engine, class T = int, std::enable_if_t<std::is_integral_v<T>>* = nullptr>
2771 [[nodiscard]]
2772 inline T RandGeometric(Engine& engine, double p = 0.5)
2773 {
2774 if (!std::isfinite(p) || p <= 0.0 || p > 1.0)
2775 throw std::invalid_argument("RandGeometric: p must be in (0, 1]");
2776 std::geometric_distribution<T> dist(p);
2777 return dist(engine);
2778 }
2779
2784 template <class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
2785 [[nodiscard]]
2786 inline T RandCauchy(T a = T{0}, T b = T{1})
2787 {
2788 if (!std::isfinite(a) || !std::isfinite(b) || b <= T{0})
2789 throw std::invalid_argument("RandCauchy: invalid a or b");
2790 std::cauchy_distribution<T> dist(a, b);
2791 return dist(DefaultEngine());
2792 }
2793
2799 template <class Engine, class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
2800 [[nodiscard]]
2801 inline T RandCauchy(Engine& engine, T a = T{0}, T b = T{1})
2802 {
2803 if (!std::isfinite(a) || !std::isfinite(b) || b <= T{0})
2804 throw std::invalid_argument("RandCauchy: invalid a or b");
2805 std::cauchy_distribution<T> dist(a, b);
2806 return dist(engine);
2807 }
2808
2813 template <class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
2814 [[nodiscard]]
2815 inline T RandWeibull(T a = T{1}, T b = T{1})
2816 {
2817 if (!std::isfinite(a) || !std::isfinite(b) || a <= T{0} || b <= T{0})
2818 throw std::invalid_argument("RandWeibull: invalid a or b");
2819 std::weibull_distribution<T> dist(a, b);
2820 return dist(DefaultEngine());
2821 }
2822
2828 template <class Engine, class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
2829 [[nodiscard]]
2830 inline T RandWeibull(Engine& engine, T a = T{1}, T b = T{1})
2831 {
2832 if (!std::isfinite(a) || !std::isfinite(b) || a <= T{0} || b <= T{0})
2833 throw std::invalid_argument("RandWeibull: invalid a or b");
2834 std::weibull_distribution<T> dist(a, b);
2835 return dist(engine);
2836 }
2837
2842 template <class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
2843 [[nodiscard]]
2844 inline T RandExtremeValue(T a = T{0}, T b = T{1})
2845 {
2846 if (!std::isfinite(a) || !std::isfinite(b) || b <= T{0})
2847 throw std::invalid_argument("RandExtremeValue: invalid a or b");
2848 std::extreme_value_distribution<T> dist(a, b);
2849 return dist(DefaultEngine());
2850 }
2851
2857 template <class Engine, class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
2858 [[nodiscard]]
2859 inline T RandExtremeValue(Engine& engine, T a = T{0}, T b = T{1})
2860 {
2861 if (!std::isfinite(a) || !std::isfinite(b) || b <= T{0})
2862 throw std::invalid_argument("RandExtremeValue: invalid a or b");
2863 std::extreme_value_distribution<T> dist(a, b);
2864 return dist(engine);
2865 }
2866
2870 template <class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
2871 [[nodiscard]]
2872 inline T RandChiSquared(T n = T{1})
2873 {
2874 if (!std::isfinite(n) || n <= T{0})
2875 throw std::invalid_argument("RandChiSquared: n must be positive");
2876 std::chi_squared_distribution<T> dist(n);
2877 return dist(DefaultEngine());
2878 }
2879
2884 template <class Engine, class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
2885 [[nodiscard]]
2886 inline T RandChiSquared(Engine& engine, T n = T{1})
2887 {
2888 if (!std::isfinite(n) || n <= T{0})
2889 throw std::invalid_argument("RandChiSquared: n must be positive");
2890 std::chi_squared_distribution<T> dist(n);
2891 return dist(engine);
2892 }
2893
2897 template <class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
2898 [[nodiscard]]
2899 inline T RandStudentT(T n = T{1})
2900 {
2901 if (!std::isfinite(n) || n <= T{0})
2902 throw std::invalid_argument("RandStudentT: n must be positive");
2903 std::student_t_distribution<T> dist(n);
2904 return dist(DefaultEngine());
2905 }
2906
2911 template <class Engine, class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
2912 [[nodiscard]]
2913 inline T RandStudentT(Engine& engine, T n = T{1})
2914 {
2915 if (!std::isfinite(n) || n <= T{0})
2916 throw std::invalid_argument("RandStudentT: n must be positive");
2917 std::student_t_distribution<T> dist(n);
2918 return dist(engine);
2919 }
2920
2925 template <class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
2926 [[nodiscard]]
2927 inline T RandFisherF(T m = T{1}, T n = T{1})
2928 {
2929 if (!std::isfinite(m) || !std::isfinite(n) || m <= T{0} || n <= T{0})
2930 throw std::invalid_argument("RandFisherF: invalid m or n");
2931 std::fisher_f_distribution<T> dist(m, n);
2932 return dist(DefaultEngine());
2933 }
2934
2940 template <class Engine, class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
2941 [[nodiscard]]
2942 inline T RandFisherF(Engine& engine, T m = T{1}, T n = T{1})
2943 {
2944 if (!std::isfinite(m) || !std::isfinite(n) || m <= T{0} || n <= T{0})
2945 throw std::invalid_argument("RandFisherF: invalid m or n");
2946 std::fisher_f_distribution<T> dist(m, n);
2947 return dist(engine);
2948 }
2949
2955 template <class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
2956 [[nodiscard]]
2957 inline T RandBeta(T a = T{1}, T b = T{1})
2958 {
2959 return RandBeta(DefaultEngine(), a, b);
2960 }
2961
2967 template <class Engine, class T = double, std::enable_if_t<std::is_floating_point_v<T>>* = nullptr>
2968 [[nodiscard]]
2969 inline T RandBeta(Engine& engine, T a = T{1}, T b = T{1})
2970 {
2971 if (!std::isfinite(a) || !std::isfinite(b) || a <= T{0} || b <= T{0})
2972 throw std::invalid_argument("RandBeta: invalid a or b");
2973 std::gamma_distribution<T> distA(a, T{1});
2974 std::gamma_distribution<T> distB(b, T{1});
2975 const T x = distA(engine);
2976 const T y = distB(engine);
2977 const T sum = x + y;
2978 if (sum == T{0} || !std::isfinite(sum))
2979 {
2980 if (std::isinf(x) && !std::isinf(y)) return T{1};
2981 if (!std::isinf(x) && std::isinf(y)) return T{0};
2982 const double ratio = 1.0 / (1.0 + (static_cast<double>(b) / static_cast<double>(a)));
2983 return RandBool(engine, ratio) ? T{1} : T{0};
2984 }
2985 return x / sum;
2986 }
2987
2991 template <int N, class T = std::uint64_t, std::enable_if_t<std::is_integral_v<T> && (N > 0) && (N <= 64) && (N <= static_cast<int>(sizeof(T) * 8))>* = nullptr>
2992 [[nodiscard]]
2993 inline T RandBits() noexcept
2994 {
2995 return RandBits<N, T>(DefaultEngine());
2996 }
2997
3002 template <int N, class T = std::uint64_t, class Engine, std::enable_if_t<std::is_integral_v<T> && (N > 0) && (N <= 64) && (N <= static_cast<int>(sizeof(T) * 8))>* = nullptr>
3003 [[nodiscard]]
3004 inline T RandBits(Engine& engine) noexcept
3005 {
3006 if constexpr (N == 64)
3007 return static_cast<T>(engine());
3008 else
3009 return static_cast<T>(engine() & ((N >= 64) ? ~std::uint64_t{0} : ((std::uint64_t{1} << (N & 63)) - 1)));
3010 }
3011
3016 template <class Engine>
3017 [[nodiscard]]
3018 inline std::string RandUUID(Engine& engine)
3019 {
3020 static constexpr char hex[] = "0123456789abcdef";
3021 std::string uuid(36, '-');
3022 const std::uint64_t u1 = detail::Generate64Bits(engine);
3023 const std::uint64_t u2 = detail::Generate64Bits(engine);
3024
3025 for (int i = 0; i < 8; ++i)
3026 uuid[i] = hex[(u1 >> (i * 4)) & 0xFU];
3027 for (int i = 0; i < 4; ++i)
3028 uuid[9 + i] = hex[(u1 >> ((8 + i) * 4)) & 0xFU];
3029 uuid[14] = '4';
3030 for (int i = 1; i < 4; ++i)
3031 uuid[14 + i] = hex[(u1 >> ((12 + i) * 4)) & 0xFU];
3032 uuid[19] = hex[8 + ((u2 >> 0) & 0x3U)];
3033 for (int i = 1; i < 4; ++i)
3034 uuid[19 + i] = hex[(u2 >> (i * 4)) & 0xFU];
3035 for (int i = 0; i < 12; ++i)
3036 uuid[24 + i] = hex[(u2 >> ((4 + i) * 4)) & 0xFU];
3037
3038 return uuid;
3039 }
3040
3041 [[nodiscard]]
3042 inline std::string RandUUID()
3043 {
3044 return RandUUID(DefaultEngine());
3045 }
3046
3048 //
3049 // 静态断言:确认引擎满足 UniformRandomBitGenerator 要求
3050 //
3051
3052 static_assert(std::is_same_v<SplitMix64::result_type, std::uint64_t>);
3053 static_assert(std::is_same_v<Xoshiro256StarStar::result_type, std::uint64_t>);
3054 static_assert(std::is_same_v<Xoroshiro128StarStar::result_type, std::uint64_t>);
3055 static_assert(std::is_same_v<Xoshiro128StarStar::result_type, std::uint32_t>);
3056 static_assert(std::is_same_v<Xoroshiro64StarStar::result_type, std::uint32_t>);
3057 static_assert(std::is_same_v<SFC64::result_type, std::uint64_t>);
3058 static_assert(std::is_same_v<RomuDuoJr::result_type, std::uint64_t>);
3059 static_assert(std::is_same_v<ChaCha20::result_type, std::uint64_t>);
3060 static_assert(SplitMix64::min() < SplitMix64::max());
3061 static_assert(Xoshiro256StarStar::min() < Xoshiro256StarStar::max());
3062 static_assert(Xoroshiro128StarStar::min() < Xoroshiro128StarStar::max());
3063 static_assert(Xoshiro128StarStar::min() < Xoshiro128StarStar::max());
3064 static_assert(Xoroshiro64StarStar::min() < Xoroshiro64StarStar::max());
3065 static_assert(SFC64::min() < SFC64::max());
3066 static_assert(RomuDuoJr::min() < RomuDuoJr::max());
3067 static_assert(ChaCha20::min() < ChaCha20::max());
3068
3069 // ========================================================================
3070 // 流式运算符 operator<< / operator>>
3071 // 仅对 state_type 为可索引容器类的引擎生效(is_serializable_engine_v)
3072 // SplitMix64(state_type = uint64_t 标量)不支持,由 is_indexable_state_v 排除
3073 // 格式兼容 std::random_engine:空格分隔的十进制数序列
3074 // ========================================================================
3075
3076 // 流式输出引擎状态
3077 template <class CharT, class Traits, class Engine,
3078 std::enable_if_t<detail::is_serializable_engine_v<Engine>>* = nullptr>
3079 std::basic_ostream<CharT, Traits>&
3080 operator<<(std::basic_ostream<CharT, Traits>& os, const Engine& engine)
3081 {
3082 typename std::basic_ostream<CharT, Traits>::sentry ok(os);
3083 if (!ok) return os;
3084
3085 const auto flags = os.flags();
3086 os.setf(std::ios_base::dec, std::ios_base::basefield);
3087
3088 auto state = engine.serialize();
3089 auto it = state.begin();
3090 if (it != state.end())
3091 {
3092 os << *it;
3093 for (++it; it != state.end(); ++it)
3094 os << os.widen(' ') << *it;
3095 }
3096
3097 os.flags(flags);
3098 return os;
3099 }
3100
3101 // 流式恢复引擎状态
3102 // 若解析失败(读取不足、流错误或状态非法/全零),setstate(failbit) 且引擎状态保持不变
3103 // (与 std::random_engine 一致:先读取到临时 state,全部成功才 deserialize)
3104 template <class CharT, class Traits, class Engine,
3105 std::enable_if_t<detail::is_serializable_engine_v<Engine>>* = nullptr>
3106 std::basic_istream<CharT, Traits>&
3107 operator>>(std::basic_istream<CharT, Traits>& is, Engine& engine)
3108 {
3109 typename std::basic_istream<CharT, Traits>::sentry ok(is);
3110 if (!ok) return is;
3111
3112 const auto flags = is.flags();
3113 is.setf(std::ios_base::dec, std::ios_base::basefield);
3114 is.setf(std::ios_base::skipws);
3115
3116 typename Engine::state_type state{};
3117 std::size_t i = 0;
3118 for (; i < state.size() && is; ++i)
3119 is >> state[i];
3120
3121 if (i == state.size() && is && detail::IsValidState(state))
3122 {
3123 engine.deserialize(state);
3124 }
3125 else
3126 {
3127 is.setstate(std::ios_base::failbit);
3128 }
3129
3130 is.flags(flags);
3131 return is;
3132 }
3133
3134}
3135
3136#undef RANDX_NODISCARD_CXX20
#define RANDX_NODISCARD_CXX20
定义 RandX_Cpp17.hpp:137
ChaCha20 密码学安全伪随机数生成器(CSPRNG),64 位输出,符合 RFC 8439。
定义 RandX.hpp:716
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:778
ChaCha20(ChaCha20 &&other) noexcept
~ChaCha20() noexcept
RomuDuoJr 伪随机数生成器,64 位输出,周期估计 >= 2^51。
定义 RandX.hpp:660
std::array< std::uint64_t, N > state_type
< 输出类型
定义 RandX_Cpp17.hpp:290
RANDX_NODISCARD_CXX20 constexpr RomuDuoJr(state_type state) noexcept
从状态数组直接构造
定义 RandX_Cpp17.hpp:697
constexpr RomuDuoJr() noexcept
< 状态类型(2×uint64)
定义 RandX_Cpp17.hpp:678
RANDX_NODISCARD_CXX20 constexpr RomuDuoJr(SeedSeq &seq)
从 std::seed_seq 播种
定义 RandX_Cpp17.hpp:691
RANDX_NODISCARD_CXX20 constexpr RomuDuoJr(std::uint64_t seed) noexcept
以指定种子构造引擎
定义 RandX_Cpp17.hpp:683
std::uint64_t result_type
定义 RandX_Cpp17.hpp:289
constexpr result_type operator()() noexcept
生成下一个 64 位随机数
SFC64(Small Fast Counter)伪随机数生成器,64 位输出,周期 >= 2^64。
定义 RandX.hpp:617
RANDX_NODISCARD_CXX20 constexpr SFC64(SeedSeq &seq)
从 std::seed_seq 播种(填充 3 状态字 + counter=1 + 12 轮预热)
std::uint64_t result_type
定义 RandX_Cpp17.hpp:289
RANDX_NODISCARD_CXX20 constexpr SFC64(std::uint64_t seed) noexcept
以指定种子构造引擎(SplitMix64 填充 3 状态字 + counter=1 + 12 轮预热)
constexpr SFC64() noexcept
< 状态类型(4×uint64)
定义 RandX_Cpp17.hpp:635
RANDX_NODISCARD_CXX20 constexpr SFC64(state_type state) noexcept
从状态数组直接构造
定义 RandX_Cpp17.hpp:652
constexpr result_type operator()() noexcept
生成下一个 64 位随机数
std::array< std::uint64_t, N > state_type
< 输出类型
定义 RandX_Cpp17.hpp:290
SplitMix64 伪随机数生成器,64 位输出,周期 2^64。
定义 RandX.hpp:217
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:271
RANDX_NODISCARD_CXX20 constexpr SplitMix64(SeedSeq &seq)
从 std::seed_seq 播种
Xoroshiro128** 伪随机数生成器,64 位输出,周期 2^128-1。
定义 RandX.hpp:462
RANDX_NODISCARD_CXX20 constexpr Xoroshiro128StarStar(state_type state) noexcept
从状态数组直接构造
定义 RandX_Cpp17.hpp:500
std::uint64_t result_type
定义 RandX_Cpp17.hpp:289
constexpr result_type operator()() noexcept
生成下一个 64 位随机数
RANDX_NODISCARD_CXX20 constexpr Xoroshiro128StarStar(SeedSeq &seq)
从 std::seed_seq 播种
定义 RandX_Cpp17.hpp:494
RANDX_NODISCARD_CXX20 constexpr Xoroshiro128StarStar(std::uint64_t seed) noexcept
以指定种子构造引擎
定义 RandX_Cpp17.hpp:486
constexpr Xoroshiro128StarStar() noexcept
< 状态类型(2×uint64)
定义 RandX_Cpp17.hpp:481
std::array< std::uint64_t, N > state_type
< 输出类型
定义 RandX_Cpp17.hpp:290
Xoroshiro64** 伪随机数生成器,32 位输出,周期 2^64-1。
定义 RandX.hpp:572
std::array< std::uint32_t, N > state_type
< 输出类型
定义 RandX_Cpp17.hpp:290
constexpr Xoroshiro64StarStar() noexcept
< 状态类型(2×uint32)
定义 RandX_Cpp17.hpp:591
RANDX_NODISCARD_CXX20 constexpr Xoroshiro64StarStar(state_type state) noexcept
从状态数组直接构造
定义 RandX_Cpp17.hpp:610
constexpr result_type operator()() noexcept
生成下一个 32 位随机数
RANDX_NODISCARD_CXX20 constexpr Xoroshiro64StarStar(SeedSeq &seq)
从 std::seed_seq 播种
定义 RandX_Cpp17.hpp:604
std::uint32_t result_type
定义 RandX_Cpp17.hpp:289
RANDX_NODISCARD_CXX20 constexpr Xoroshiro64StarStar(std::uint64_t seed) noexcept
以指定种子构造引擎
定义 RandX_Cpp17.hpp:596
Xoshiro128** 伪随机数生成器,32 位输出,周期 2^128-1。
定义 RandX.hpp:517
std::uint32_t result_type
定义 RandX_Cpp17.hpp:289
RANDX_NODISCARD_CXX20 constexpr Xoshiro128StarStar(std::uint64_t seed) noexcept
以指定种子构造引擎
定义 RandX_Cpp17.hpp:541
constexpr result_type operator()() noexcept
生成下一个 32 位随机数
RANDX_NODISCARD_CXX20 constexpr Xoshiro128StarStar(SeedSeq &seq)
从 std::seed_seq 播种
定义 RandX_Cpp17.hpp:549
RANDX_NODISCARD_CXX20 constexpr Xoshiro128StarStar(state_type state) noexcept
从状态数组直接构造
定义 RandX_Cpp17.hpp:555
std::array< std::uint32_t, N > state_type
< 输出类型
定义 RandX_Cpp17.hpp:290
constexpr Xoshiro128StarStar() noexcept
< 状态类型(4×uint32)
定义 RandX_Cpp17.hpp:536
Xoshiro256** 伪随机数生成器,64 位输出,周期 2^256-1。
定义 RandX.hpp:407
std::array< std::uint64_t, N > state_type
< 输出类型
定义 RandX_Cpp17.hpp:290
std::uint64_t result_type
定义 RandX_Cpp17.hpp:289
RANDX_NODISCARD_CXX20 constexpr Xoshiro256StarStar(state_type state) noexcept
从状态数组直接构造
定义 RandX_Cpp17.hpp:445
RANDX_NODISCARD_CXX20 constexpr Xoshiro256StarStar(SeedSeq &seq)
从 std::seed_seq 播种
定义 RandX_Cpp17.hpp:439
constexpr Xoshiro256StarStar() noexcept
< 状态类型(4×uint64)
定义 RandX_Cpp17.hpp:426
RANDX_NODISCARD_CXX20 constexpr Xoshiro256StarStar(std::uint64_t seed) noexcept
以指定种子构造引擎
定义 RandX_Cpp17.hpp:431
constexpr result_type operator()() noexcept
生成下一个 64 位随机数
bool RandBernoulli(double p=0.5)
伯努利分布(RandBool 的别名封装,对齐 <random> 命名)
定义 RandX.hpp:1706
bool RandBool(double p=0.5)
生成随机布尔值
定义 RandX.hpp:1682
float RandCanonicalFloat() noexcept
生成 [0.0f, 1.0f) 半开区间的单精度浮点数(直通 Bit-Extraction 极速 API)
定义 RandX.hpp:1673
T RandReal(T min=T{0}, T max=T{1})
生成 [min, max) 范围内的随机浮点数
定义 RandX.hpp:1649
CharT RandChar(CharT min, CharT max)
生成 [min, max] 范围内的随机字符
定义 RandX.hpp:1731
T RandCanonical() noexcept
采用无偏 Bit-Extraction 直通算法生成 [0, 1) 半开区间的随机浮点数(默认线程引擎)
定义 RandX.hpp:1659
T RandInt(T min, T max)
生成 [min, max] 范围内的随机整数
定义 RandX.hpp:1627
decltype(auto) RandElement(Container &c)
从容器中随机取一个元素(左值容器,返回引用)
定义 RandX.hpp:1790
std::uint64_t SecureSeed()
生成密码学安全的 64 位随机种子
定义 RandX.hpp:1370
void SecureRandomBytes(void *buf, std::size_t n)
用 OS 密码学熵源填充 [buf, buf+n) 字节
定义 RandX.hpp:1360
void ReseedRandom()
重置默认引擎为真随机种子
定义 RandX.hpp:1610
bool IsOsCryptoEntropyAvailable() noexcept
检测 OS 密码学熵源是否可用
定义 RandX.hpp:1381
void Reseed(std::uint64_t seed)
重置默认引擎的种子(用于测试复现)
定义 RandX.hpp:1604
void RandFill(It first, It last, T min, T max)
用 [min, max] 范围的随机整数填充迭代器区间
定义 RandX.hpp:1940
void RandShuffle(Container &&c)
随机打乱容器
定义 RandX.hpp:1926
WeightContainer::size_type RandWeighted(const WeightContainer &weights)
按权重随机选取索引
定义 RandX.hpp:2076
CharSet
定义 RandX.hpp:2221
auto RandSample(const Container &c, typename Container::size_type n)
无放回抽样:从容器中随机抽取 n 个元素(Fisher-Yates 前 n 步)
定义 RandX.hpp:2305
std::vector< T > RandVector(T min, T max, std::size_t n)
生成含 n 个随机整数的 vector
定义 RandX.hpp:2002
T RandNormal(T mean=T{0}, T stddev=T{1})
生成正态分布随机数
定义 RandX.hpp:1900
@ Upper
定义 RandX.hpp:2225
@ Base64
定义 RandX.hpp:2229
@ Base64UrlSafe
定义 RandX.hpp:2230
@ Printable
定义 RandX.hpp:2228
@ Alpha
定义 RandX.hpp:2223
@ Digit
定义 RandX.hpp:2226
@ Hex
定义 RandX.hpp:2227
@ Lower
定义 RandX.hpp:2224
@ Alphanumeric
定义 RandX.hpp:2222
constexpr state_type serialize() const noexcept
序列化引擎状态
定义 RandX.hpp:1119
constexpr void longJump() noexcept
前进 2^96 步,用于创建更稀疏的并行子序列
定义 RandX.hpp:1188
constexpr std::array< std::uint64_t, N > generateSeedSequence() noexcept
生成 N 个高质量的 64 位种子序列
定义 RandX.hpp:1097
constexpr result_type operator()() noexcept
生成下一个 32 位随机数
定义 RandX.hpp:1227
constexpr bool IsAllZero(const std::array< std::uint64_t, N > &state) noexcept
定义 RandX.hpp:182
constexpr void jump() noexcept
前进 2^128 步,用于创建并行子序列
定义 RandX.hpp:1151
static constexpr result_type min() noexcept
输出范围下界
定义 RandX.hpp:763
ChaCha20(const ChaCha20 &)=delete
ChaCha20()
构造方式 1:从 OS 熵自动播种(密码学安全,默认)
定义 RandX.hpp:1438
std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const Engine &engine)
定义 RandX.hpp:1021
constexpr RomuDuoJr() noexcept
< 状态类型(2×uint64)
定义 RandX.hpp:668
void ResetThreadLocalEngine()
重新播种当前线程的默认引擎(用于 POSIX fork() 产生子进程后重置引擎状态)
定义 RandX.hpp:1345
std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &is, Engine &engine)
定义 RandX.hpp:1045
constexpr result_type operator()() noexcept
生成下一个 32 位随机数
定义 RandX.hpp:1198
constexpr result_type operator()() noexcept
生成下一个 64 位随机数
定义 RandX.hpp:1088
constexpr SFC64() noexcept
< 状态类型(4×uint64)
定义 RandX.hpp:625
constexpr void jump() noexcept
前进 2^64 步,用于创建并行子序列
定义 RandX.hpp:1211
constexpr result_type operator()() noexcept
生成下一个 64 位随机数
定义 RandX.hpp:1171
static constexpr result_type min() noexcept
输出范围下界
定义 RandX.hpp:1109
constexpr void longJump() noexcept
前进 2^192 步,用于创建更稀疏的并行子序列
定义 RandX.hpp:1159
constexpr void discard(unsigned long long n) noexcept
跳过 n 个输出
定义 RandX.hpp:1129
constexpr bool IsValidState(const State &state) noexcept
定义 RandX.hpp:198
constexpr SplitMix64(state_type state=DefaultSeed) noexcept
以指定状态构造引擎
定义 RandX.hpp:1076
constexpr double DoubleFromBits(Uint64 i) noexcept
定义 RandX.hpp:805
static constexpr int Bits
定义 RandX.hpp:330
ChaCha20 & operator=(const ChaCha20 &)=delete
Xoshiro256StarStar & DefaultEngine()
定义 RandX.hpp:1338
void discard(unsigned long long n)
跳过 n 个输出
定义 RandX.hpp:1597
constexpr result_type operator()() noexcept
生成下一个 64 位随机数
定义 RandX.hpp:1277
constexpr result_type operator()() noexcept
生成下一个 64 位随机数
定义 RandX.hpp:1290
std::uint64_t result_type
输出类型
定义 RandX.hpp:221
constexpr std::uint64_t RotL(const std::uint64_t x, const int s) noexcept
定义 RandX.hpp:168
constexpr Xoshiro256StarStar() noexcept
< 状态类型(4×uint64)
定义 RandX.hpp:415
std::uint64_t RandomSeed()
生成非确定性的 64 位种子
定义 RandX.hpp:1307
constexpr result_type operator()() noexcept
生成下一个 64 位随机数
定义 RandX.hpp:1138
void reseed()
从 OS 熵重新播种
定义 RandX.hpp:1555
constexpr float FloatFromBits(Uint32 i) noexcept
定义 RandX.hpp:799
std::array< ResultType, N > state_type
定义 RandX.hpp:287
constexpr void deserialize(state_type state) noexcept
从状态恢复引擎
定义 RandX.hpp:1124
constexpr void jumpPoly(const std::uint64_t(&poly)[K]) noexcept
定义 RandX.hpp:379
std::uint64_t result_type
输出类型
定义 RandX.hpp:719
constexpr void jump() noexcept
前进 2^64 步,用于创建并行子序列
定义 RandX.hpp:1182
std::uint64_t state_type
状态类型(1×uint64)
定义 RandX.hpp:220
static constexpr result_type max() noexcept
输出范围上界
定义 RandX.hpp:768
static constexpr result_type max() noexcept
输出范围上界
定义 RandX.hpp:1114
~ChaCha20() noexcept
定义 RandX.hpp:1431
constexpr void longJump() noexcept
前进 2^96 步,用于创建更稀疏的并行子序列
定义 RandX.hpp:1217
T RandChiSquared(T n=T{1})
生成卡方分布随机数
定义 RandX.hpp:2878
std::string RandString(std::size_t length, std::string_view charset="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
生成指定长度的随机字符串
定义 RandX.hpp:2563
T RandExtremeValue(T a=T{0}, T b=T{1})
生成极值分布(Gumbel)随机数
定义 RandX.hpp:2850
T RandFisherF(T m=T{1}, T n=T{1})
生成 Fisher F 分布随机数
定义 RandX.hpp:2933
T RandCauchy(T a=T{0}, T b=T{1})
生成柯西分布随机数
定义 RandX.hpp:2792
T RandStudentT(T n=T{1})
生成学生 t 分布随机数
定义 RandX.hpp:2905
T RandGamma(T alpha=T{1}, T beta=T{1})
生成伽马分布随机数
定义 RandX.hpp:2678
T RandWeibull(T a=T{1}, T b=T{1})
生成韦布尔分布随机数
定义 RandX.hpp:2821
T RandExp(T lambda=T{1})
生成指数分布随机数
定义 RandX.hpp:2621
T RandLogNormal(T mean=T{0}, T stddev=T{1})
生成对数正态分布随机数
定义 RandX.hpp:2736
T RandBeta(T a=T{1}, T b=T{1})
生成 Beta 分布随机数
定义 RandX.hpp:2963
constexpr Engine MakeStreamEngine(std::uint64_t streamId, std::uint64_t seed=DefaultSeed)
从同一种子创建第 streamId 个不重叠子序列的引擎
定义 RandX.hpp:3068
T RandBinomial(T t=1, double p=0.5)
生成二项分布随机数
定义 RandX.hpp:2707
T RandGeometric(double p=0.5)
生成几何分布随机数(首次成功前的失败次数)
定义 RandX.hpp:2764
T RandPoisson(double mean=1.0)
生成泊松分布随机数
定义 RandX.hpp:2648
std::string RandUUID(Engine &engine)
生成随机 UUID v4 字符串
定义 RandX.hpp:3026
定义 RandX.hpp:166
bool GetOsEntropyBytes(void *buf, std::size_t n) noexcept
定义 RandX.hpp:854
constexpr std::uint32_t ChaCha20Constants[4]
定义 RandX.hpp:916
constexpr bool is_rand_fillable_v
定义 RandX_Cpp17.hpp:1274
bool HardwareRand64(std::uint64_t &out) noexcept
定义 RandX.hpp:821
constexpr bool is_serializable_engine_v
定义 RandX_Cpp17.hpp:1310
constexpr std::uint64_t ChaCha20ReseedThreshold
定义 RandX.hpp:921
static void ChaCha20QuarterRound(std::uint32_t &a, std::uint32_t &b, std::uint32_t &c, std::uint32_t &d) noexcept
定义 RandX.hpp:924
constexpr bool is_random_access_iterator_v
定义 RandX_Cpp17.hpp:1228
constexpr bool is_input_iterator_v
定义 RandX_Cpp17.hpp:1232
constexpr bool is_character_v
定义 RandX_Cpp17.hpp:1205
std::uint64_t Generate64Bits(Engine &engine)
定义 RandX.hpp:935
bool HasCryptoGradeOsEntropy() noexcept
定义 RandX.hpp:905
constexpr bool is_random_access_container_v
定义 RandX_Cpp17.hpp:1246
static void SecureWipe(void *ptr, std::size_t len) noexcept
定义 RandX.hpp:813
constexpr std::uint64_t HashSetThresholdK
定义 RandX.hpp:2209
constexpr bool is_indexable_state_v
定义 RandX_Cpp17.hpp:1290
定义 RandX.hpp:150
constexpr std::uint64_t DefaultSeed
定义 RandX.hpp:152
定义 RandX.hpp:285
static constexpr result_type min() noexcept
定义 RandX_Cpp17.hpp:295
constexpr EngineBase(SeedSeq &seq)
定义 RandX_Cpp17.hpp:360
constexpr EngineBase(std::uint64_t seed) noexcept
定义 RandX_Cpp17.hpp:380
constexpr void discard(unsigned long long z) noexcept
定义 RandX_Cpp17.hpp:306
constexpr state_type serialize() const noexcept
定义 RandX_Cpp17.hpp:313
static constexpr result_type max() noexcept
定义 RandX_Cpp17.hpp:301
constexpr void deserialize(const state_type &s) noexcept
定义 RandX_Cpp17.hpp:318
std::array< std::uint64_t, N > state_type
定义 RandX_Cpp17.hpp:290
constexpr EngineBase(const state_type &state) noexcept
定义 RandX_Cpp17.hpp:346
constexpr void jumpPoly(const ResultType(&poly)[K]) noexcept
定义 RandX_Cpp17.hpp:390
friend bool operator!=(const EngineBase &lhs, const EngineBase &rhs) noexcept
定义 RandX_Cpp17.hpp:334
friend bool operator==(const EngineBase &lhs, const EngineBase &rhs) noexcept
定义 RandX_Cpp17.hpp:329
定义 RandX_Cpp17.hpp:1180
定义 RandX_Cpp17.hpp:1185
定义 RandX_Cpp17.hpp:1202
定义 RandX_Cpp17.hpp:1278
定义 RandX_Cpp17.hpp:1219
定义 RandX_Cpp17.hpp:1264
定义 RandX_Cpp17.hpp:1209
定义 RandX_Cpp17.hpp:1294