7#include "core/fxcrt/fx_random.h"
9#include "build/build_config.h"
10#include "core/fxcrt/fx_memory.h"
11#include "core/fxcrt/fx_string.h"
12#include "core/fxcrt/fx_system.h"
16#define MT_Matrix_A 0x9908b0df
17#define MT_Upper_Mask 0x80000000
18#define MT_Lower_Mask 0x7fffffff
34bool g_bHaveGlobalSeed =
false;
35uint32_t g_nGlobalSeed = 0;
38bool GenerateSeedFromCryptoRandom(uint32_t* pSeed) {
40 if (!::CryptAcquireContext(&hCP,
nullptr,
nullptr, PROV_RSA_FULL, 0) ||
44 ::CryptGenRandom(hCP,
sizeof(uint32_t),
reinterpret_cast<uint8_t*>(pSeed));
45 ::CryptReleaseContext(hCP, 0);
50uint32_t GenerateSeedFromEnvironment() {
52 uintptr_t p =
reinterpret_cast<uintptr_t>(&c);
53 uint32_t seed = ~
static_cast<uint32_t>(p >> 3);
57 seed ^=
static_cast<uint32_t>(st.wSecond) * 1000000;
58 seed ^=
static_cast<uint32_t>(st.wMilliseconds) * 1000;
59 seed ^= GetCurrentProcessId();
62 gettimeofday(&tv,
nullptr);
63 seed ^=
static_cast<uint32_t>(tv.tv_sec) * 1000000;
64 seed ^=
static_cast<uint32_t>(tv.tv_usec);
65 seed ^=
static_cast<uint32_t>(getpid());
70void* ContextFromNextGlobalSeed() {
71 if (!g_bHaveGlobalSeed) {
73 if (!GenerateSeedFromCryptoRandom(&g_nGlobalSeed))
74 g_nGlobalSeed = GenerateSeedFromEnvironment();
76 g_nGlobalSeed = GenerateSeedFromEnvironment();
78 g_bHaveGlobalSeed =
true;
86 MTContext* pContext = FX_Alloc(MTContext, 1);
87 uint32_t* pBuf = pContext->mt;
89 for (uint32_t i = 1; i <
MT_N; i++)
90 pBuf[i] = (1812433253UL * (pBuf[i - 1] ^ (pBuf[i - 1] >> 30)) + i);
97 MTContext* pMTC =
static_cast<MTContext*>(pContext);
98 uint32_t* pBuf = pMTC->mt;
100 if (pMTC->mti >=
MT_N) {
103 for (kk = 0; kk <
MT_N -
MT_M; kk++) {
105 pBuf[kk] = pBuf[kk +
MT_M] ^ (v >> 1) ^ mag[v & 1];
107 for (; kk <
MT_N - 1; kk++) {
109 pBuf[kk] = pBuf[kk + (
MT_M -
MT_N)] ^ (v >> 1) ^ mag[v & 1];
112 pBuf[
MT_N - 1] = pBuf[
MT_M - 1] ^ (v >> 1) ^ mag[v & 1];
115 v = pBuf[pMTC->mti++];
117 v ^= (v << 7) & 0x9d2c5680UL;
118 v ^= (v << 15) & 0xefc60000UL;
128 void* pContext = ContextFromNextGlobalSeed();
void FX_Random_GenerateMT(uint32_t *pBuffer, int32_t iCount)
void * FX_Random_MT_Start(uint32_t dwSeed)
uint32_t FX_Random_MT_Generate(void *pContext)
void FX_Random_MT_Close(void *pContext)