Intel在IVB架構的第三代CPU酷睿處理器(2012年開始生產)內置了一個利用電阻熱噪聲取得硬件真隨機數的功能。
關於真隨機數和僞隨機數的區別,以及世上是否存在真隨機數等哲學爭論不在本文討論範圍。
下面給出delphi代碼,一共4個函數,具體使用的是兩個函數:
RdRand_isSupported 判斷當前cpu是否支持該功能,
rdrand_16 取得16位隨機數到aex寄存器,(看了一下intel開發手冊似乎16位和32位隨機數指令是一樣的,該函數返回的其實是一個32位隨機數,具體情況大家自行測試一下)。另外該函數內沒有判斷cpu是否支持該指令,所以請在程序開始階段或者其他相應地方調用RdRand_isSupported來判斷cpu是否支持該功能。
function GetCpuId(): UINT;
var
bException: BOOL;
//szCpu: array [0 .. 15] of BYTE;
uCpuID: UINT;
begin
Result := 0;
// ZeroMemory(@szCpu, sizeof(szCpu));
uCpuID := 0;
bException := true;
try
asm
mov eax, 1
cpuid
{ mov dword ptr szCpu[0], ebx
mov dword ptr szCpu[4], edx
mov dword ptr szCpu[8], ecx
mov eax, 1
cpuid }
mov uCpuID, ecx
end;
except
bException := false;
end;
if bException then
Result := uCpuID;
end;
function GetCpuName(): string;
var
bException: BOOL;
szCpu: array [0 .. 15] of BYTE;
// uCpuID: UINT;
begin
Result := '';
ZeroMemory(@szCpu, sizeof(szCpu));
// uCpuID := 0;
bException := true;
try
asm
mov eax, 0
//cpuid
db 0fh,0a2h
mov dword ptr szCpu[0], ebx
mov dword ptr szCpu[4], edx
mov dword ptr szCpu[8], ecx
// mov eax, 1
// cpuid
// mov uCpuID, edx
end;
except
bException := false;
end;
if bException then
begin
Result := StrPas(PAnsiChar(@szCpu));
end;
end;
function RdRand_isSupported: boolean;
var info: dword;
ss: string;
begin
ss:= GetCpuName;
if pos('Intel',ss)=0 then
begin
result:= false;
exit;
end;
info:= GetCpuId;
// showmessage(INTTOSTR(info));
if info and $40000000=$40000000 then
result:= true
else
result:= false;
end;
function rdrand_16: dword; //取得一個16位的隨機數
asm
db $0f, $c7, $f0
end;