我无法在任何地方找到适用于Windows的任何时钟漂移RNG代码,所以我试图自己实现它。我还没有通过ent
或DIEHARD
运行这些数字,而我只是想知道这是否是远程正确的...
void QueryRDTSC(__int64* tick) {
__asm {
xor eax, eax
cpuid
rdtsc
mov edi, dword ptr tick
mov dword ptr [edi], eax
mov dword ptr [edi+4], edx
}
}
__int64 clockDriftRNG() {
__int64 CPU_start, CPU_end, OS_start, OS_end;
// get CPU ticks -- uses RDTSC on the Processor
QueryRDTSC(&CPU_start);
Sleep(1);
QueryRDTSC(&CPU_end);
// get OS ticks -- uses the Motherboard clock
QueryPerformanceCounter((LARGE_INTEGER*)&OS_start);
Sleep(1);
QueryPerformanceCounter((LARGE_INTEGER*)&OS_end);
// CPU clock is ~1000x faster than mobo clock
// return raw
return ((CPU_end - CPU_start)/(OS_end - OS_start));
// or
// return a random number from 0 to 9
// return ((CPU_end - CPU_start)/(OS_end - OS_start)%10);
}
如果你想知道为什么我Sleep(1)
,那是因为如果我不这样做,OS_end - OS_start
会一直返回0
(因为定时器分辨率不好,我认为)。
基本上,(CPU_end - CPU_start)/(OS_end - OS_start)
总是返回围绕 1000
,并根据CPU负载的熵略有变化,可能是温度,石英晶体振动不完善等等。
无论如何,这些数字的分布相当不错,但这可能是完全错误的。我不知道。
编辑:根据Stephen Nutt的说法,Sleep(1)
可能没有做我期望的事情,所以我试图使用以下代替Sleep(1)
:
void loop() {
__asm {
mov ecx, 1000
cylcles:
nop
loop cylcles
}
}
答案 0 :(得分:1)
考虑一些乘法来增加范围。然后使用结果为PRNG播种。
答案 1 :(得分:1)
Sleep功能受系统时钟分辨率的限制,因此Sleep (1)
可能无法满足您的需求。