#include "SafeRNG.h" #include #include #include #include #include bool RandomNumberGenerator::FillWithOpenSSLRandom(unsigned char* dst, size_t len) noexcept { try { while (len > 0) { int chunk = (len > static_cast(INT_MAX)) ? INT_MAX : static_cast(len); // RAND_bytes 返回 1 成功 int rc = RAND_bytes(dst, chunk); if (rc != 1) return false; dst += chunk; len -= static_cast(chunk); } return true; } catch (...) { return false; } } bool RandomNumberGenerator::FillWithSTDMT19937_64(unsigned char* dst, size_t len) noexcept { try { // 先尝试用 random_device 为 mt19937_64 提供种子 std::mt19937_64 gen; try { std::random_device rd; // 将几个 rd() 的值混合到一个 seed 中 uint64_t seed = 0; for (int i = 0; i < 4; ++i) seed ^= (static_cast(rd()) + 0x9e3779b97f4a7c15ULL + (seed << 6) + (seed >> 2)); gen.seed(seed); } catch (...) { // random_device 可能抛或不可靠;退回到时间戳种子(不可预测性较低) uint64_t seed = static_cast(std::chrono::high_resolution_clock::now().time_since_epoch().count()); gen.seed(seed); } // 逐 8 字节生成并拷贝;最后处理剩余字节 while (len >= 8) { uint64_t v = gen(); std::memcpy(dst, &v, 8); dst += 8; len -= 8; } if (len > 0) { uint64_t v = gen(); std::memcpy(dst, &v, len); } return true; } catch (...) { return false; } } std::string RandomNumberGenerator::Bytes2HexString(const unsigned char* data, size_t len) noexcept { try { const char* hex_chars = "0123456789ABCDEF"; std::string out; out.resize(len * 2); for (std::size_t i = 0; i < len; ++i) { unsigned char v = data[i]; out[2 * i] = hex_chars[(v >> 4) & 0xF]; out[2 * i + 1] = hex_chars[v & 0xF]; } return out; } catch (...) { return std::string(); } } std::string RandomNumberGenerator::SecureRandomHex(size_t bytes) { if (bytes == 0) return std::string(); // 分配原始缓冲区(可能抛 bad_alloc -> catch below) unsigned char* buf = nullptr; try { buf = static_cast(::operator new(bytes)); } catch (...) { return std::string(); // 无法分配内存,返回空字符串表示失败 } bool ok = FillWithOpenSSLRandom(buf, bytes); if (!ok) { //printf_s("OpenSSL Failure!\n"); // OpenSSL 失败:使用伪随机兜底(保证会产出数据) bool ok2 = FillWithSTDMT19937_64(buf, bytes); if (!ok2) { // 极端失败:释放并返回空字符串 ::operator delete(buf); return std::string(); } } // 转 hex 并返回(Bytes2HexString 会在异常时返回空字符串) std::string hex = Bytes2HexString(buf, bytes); ::operator delete(buf); return hex; }