我正在尝试从http://isthe.com/chongo/tech/comp/fnv/实现 FNV 哈希
我将该页面上的 PowerBasic 的内联汇编转换为 Delphi。
function ReadFileToMem(sPath:string):Pointer;
var
hFile: THandle;
pBuffer: Pointer;
dSize: DWORD;
dRead: DWORD;
begin
hFile := CreateFile(PChar(sPath), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);
if hFile <> 0 then
dSize := GetFileSize(hFile, nil);
if dSize <> 0 then
begin
SetFilePointer(hFile, 0, nil, FILE_BEGIN);
GetMem(Result, dSize);
ReadFile(hFile, Result^, dSize, dRead, nil);
if dRead = 0 then
MessageBox(0, PChar('Error reading file.'), PChar('Read Error'), MB_ICONEXCLAMATION)
end;
CloseHandle(hFile);
end;
function GetPointerSize(lpBuffer: Pointer): Cardinal; // Function by ErazerZ
begin
if lpBuffer = nil then
Result := Cardinal(-1)
else
Result := Cardinal(Pointer(Cardinal(lpBuffer) -4)^) and $7FFFFFFC -4;
end;
FUNCTION FNV32( dwOffset : Pointer; dwLen : DWORD; offset_basis : DWORD) : DWORD ;
asm
mov esi, dwOffset //;esi = ptr to buffer
mov ecx, dwLen //;ecx = length of buffer (counter)
mov eax, offset_basis //;set to 2166136261 for FNV-1
mov edi, 16777619//&h01000193 //;FNV_32_PRIME = 16777619
xor ebx, ebx //;ebx = 0
@nextbyte:
mul edi //;eax = eax * FNV_32_PRIME
mov bl, [esi] //;bl = byte from esi
xor eax, ebx //;al = al xor bl
inc esi //;esi = esi + 1 (buffer pos)
dec ecx //;ecx = ecx - 1 (counter)
jnz @nextbyte //;if ecx is 0, jmp to NextByte
mov @result, eax //;else, function = eax
end;
procedure TForm1.Button1Click(Sender: TObject);
var
pFile : Pointer;
hFile : Cardinal;
begin
//Profiler1['Test'].Start;
pFile := ReadFileToMem(fn);
hFile := FNV32(pFile,GetPointerSize(pFile),2166136261);
//Profiler1['Test'].Stop;
//OutputDebugString(pchar(Profiler1['Test'].AsText[tiAll]));
OutputDebugString(pchar(inttostr(hFile)));
end;
如果给定文件的大小超过 200KB,则输出是随机(散列)数。我错过了什么吗?