7#include "core/fxcrt/fx_random.h"
11#include "build/build_config.h"
12#include "core/fxcrt/fx_memory.h"
13#include "core/fxcrt/fx_string.h"
14#include "core/fxcrt/fx_system.h"
18#define MT_Matrix_A 0x9908b0df
19#define MT_Upper_Mask 0x80000000
20#define MT_Lower_Mask 0x7fffffff
36bool g_bHaveGlobalSeed =
false;
37uint32_t g_nGlobalSeed = 0;
40bool GenerateSeedFromCryptoRandom(uint32_t* pSeed) {
42 if (!::CryptAcquireContext(&hCP,
nullptr,
nullptr, PROV_RSA_FULL, 0) ||
46 ::CryptGenRandom(hCP,
sizeof(uint32_t),
reinterpret_cast<uint8_t*>(pSeed));
47 ::CryptReleaseContext(hCP, 0);
52uint32_t GenerateSeedFromEnvironment() {
54 uintptr_t p =
reinterpret_cast<uintptr_t>(&c);
55 uint32_t seed = ~
static_cast<uint32_t>(p >> 3);
59 seed ^=
static_cast<uint32_t>(st.wSecond) * 1000000;
60 seed ^=
static_cast<uint32_t>(st.wMilliseconds) * 1000;
61 seed ^= GetCurrentProcessId();
64 gettimeofday(&tv,
nullptr);
65 seed ^=
static_cast<uint32_t>(tv.tv_sec) * 1000000;
66 seed ^=
static_cast<uint32_t>(tv.tv_usec);
67 seed ^=
static_cast<uint32_t>(getpid());
72void* ContextFromNextGlobalSeed() {
73 if (!g_bHaveGlobalSeed) {
75 if (!GenerateSeedFromCryptoRandom(&g_nGlobalSeed))
76 g_nGlobalSeed = GenerateSeedFromEnvironment();
78 g_nGlobalSeed = GenerateSeedFromEnvironment();
80 g_bHaveGlobalSeed =
true;
88 MTContext* pContext = FX_Alloc(MTContext, 1);
89 pContext->mt[0] = dwSeed;
90 for (uint32_t i = 1; i <
MT_N; i++) {
91 const uint32_t prev = pContext->mt[i - 1];
92 pContext->mt[i] = (1812433253UL * (prev ^ (prev >> 30)) + i);
99 MTContext* pMTC =
static_cast<MTContext*>(pContext);
101 if (pMTC->mti >=
MT_N) {
102 static constexpr std::array<uint32_t, 2> mag = {{0,
MT_Matrix_A}};
104 for (kk = 0; kk <
MT_N -
MT_M; kk++) {
106 pMTC->mt[kk] = pMTC->mt[kk +
MT_M] ^ (v >> 1) ^ mag[v & 1];
108 for (; kk <
MT_N - 1; kk++) {
110 pMTC->mt[kk] = pMTC->mt[kk + (
MT_M -
MT_N)] ^ (v >> 1) ^ mag[v & 1];
113 pMTC->mt[
MT_N - 1] = pMTC->mt[
MT_M - 1] ^ (v >> 1) ^ mag[v & 1];
116 v = pMTC->mt[pMTC->mti++];
118 v ^= (v << 7) & 0x9d2c5680UL;
119 v ^= (v << 15) & 0xefc60000UL;
129 void* pContext = ContextFromNextGlobalSeed();
130 for (size_t i = 0; i < pBuffer.size(); ++i) {
void * FX_Random_MT_Start(uint32_t dwSeed)
uint32_t FX_Random_MT_Generate(void *pContext)
void FX_Random_GenerateMT(pdfium::span< uint32_t > pBuffer)
void FX_Random_MT_Close(void *pContext)