#include #include #include #include #if defined(_WIN32) || defined(_WIN64) #include #else #include #endif /* ------------------------------------------------------------------------------------------------------------------ */ /* */ void c_Random_Init(void) { // 1. 获取基础日历时间(秒级) uint64_t seed_entropy = (uint64_t)time(NULL); // 2. 获取高精度硬件/OS级时间戳,阻断高频重启或高并发时的秒级碰撞 #if defined(_WIN32) || defined(_WIN64) LARGE_INTEGER perf_counter; if (QueryPerformanceCounter(&perf_counter)) { seed_entropy ^= (uint64_t)perf_counter.QuadPart; } else { seed_entropy ^= (uint64_t)GetTickCount(); } // 混合当前进程 ID seed_entropy ^= ((uint64_t)GetCurrentProcessId() << 16); #else struct timespec ts; // 优先采用高精度纳秒单调时钟 if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) { seed_entropy ^= ((uint64_t)ts.tv_sec << 32) ^ (uint64_t)ts.tv_nsec; } else if (clock_gettime(CLOCK_REALTIME, &ts) == 0) { seed_entropy ^= ((uint64_t)ts.tv_sec << 32) ^ (uint64_t)ts.tv_nsec; } // 混合当前进程 ID seed_entropy ^= ((uint64_t)getpid() << 16); #endif // 3. 核心避坑:加入运行时环境的 ASLR 栈空间地址作为环境噪声 // 局部变量在栈上的地址在每次运行时受操作系统 ASLR 影响都是随机的 volatile int dummy_stack_var = 0; uintptr_t stack_address = (uintptr_t)&dummy_stack_var; seed_entropy ^= (uint64_t)stack_address; // 4. 将采集到的 64 位熵数据进行简单混淆(对折异或),降维匹配到标准库 srand 的参数空间 unsigned int final_seed = (unsigned int)(seed_entropy ^ (seed_entropy >> 32)); // 5. 播种 srand(final_seed); } /** * @brief 生成指定闭区间 [min, max] 内的高质量均匀分布无符号整数 * * @param min 区间下界(包含) * @param max 区间上界(包含) * @return uint64_t 生成的随机数 */ uint64_t c_Random_RangeU64(uint64_t min, uint64_t max) { if (min >= max) { return min; } uint64_t range = max - min + 1; // 核心:消除模数偏差 (Modulo Bias) 算法 // 计算在 RAND_MAX(或此处为 UINT64_MAX 映射区间)内排出的残缺余数窗口 uint64_t limit = UINT64_MAX - (UINT64_MAX % range); uint64_t rand_val; do { // 拼接两个标准的 32 位随机数以组合成高质量的 64 位宽随机数源 // 若您的平台有硬件随机数(如 NDK 的 arc4random 或 x86 的 RDRAND),可在此处替换 uint64_t high = (uint32_t)rand(); uint64_t low = (uint32_t)rand(); rand_val = (high << 32) | low; } while (rand_val >= limit); // 落在残缺窗口内的数直接丢弃,重新抽取 return min + (rand_val % range); } /** * @brief 生成指定闭区间 [min, max] 内的高质量有符号整数 */ int64_t c_Random_RangeI64(int64_t min, int64_t max) { if (min >= max) return min; // 将有符号区间平移映射至无符号空间处理,完美规避符号位溢出死锁 uint64_t range = (uint64_t)(max - min); uint64_t limit = UINT64_MAX - (UINT64_MAX % (range + 1)); uint64_t rand_val; do { uint64_t high = (uint32_t)rand(); uint64_t low = (uint32_t)rand(); rand_val = (high << 32) | low; } while (rand_val >= limit); return min + (int64_t)(rand_val % (range + 1)); } /** * @brief 生成指定区间 [min, max) 内的双精度浮点数 */ double c_Random_RangeDouble(double min, double max) { if (min >= max) return min; // 将标准生成的 64 位无符号随机数归一化映射到 [0.0, 1.0) 之间 double scale = (double)rand() / ((double)RAND_MAX + 1.0); return min + scale * (max - min); }