我使用FNV来散列32位操作系统中的文件。如果我在64位操作系统中使用代码,为什么相同代码的哈希结果会有所不同?
这是我的代码:
function gethash(const dwOffset: PByteArray; const dwLen: DWORD;
const offset_basis: DWORD): DWORD;
var
i: integer;
begin
Result := offset_basis;
try
{$R-}{$I-}
for i := 0 to dwLen - 1 do
Result := (Result * 16777619) xor DWORD(dwOffset^[i]);
{$R+}{$I+}
except
;
end;
end;
答案 0 :(得分:1)
无论操作系统的位数如何,此代码都将生成相同的输出。此外,输出与过程的位数无关。也就是说,如果编译32位和64位,输出将是相同的。
因此,逻辑结论是不同的输出是由提供不同的输入引起的。
有人可能会问你为什么在代码中吞下所有异常处理程序。那一定是个坏主意。如果您提供导致访问冲突的错误参数,您将永远不会发现。我建议你删除那个异常处理程序。
为了证明我的观点,我提供了以下简单的测试程序:
{$APPTYPE CONSOLE}
uses
Winapi.Windows,
System.SysUtils;
{$R-}{$I-}
function gethash(const dwOffset: PByteArray; const dwLen: DWORD;
const offset_basis: DWORD): DWORD;
var
i: integer;
begin
Result := offset_basis;
for i := 0 to dwLen - 1 do
Result := (Result * 16777619) xor DWORD(dwOffset^[i]);
end;
procedure Main;
var
i: Integer;
buf: TBytes;
begin
SetLength(buf, 666);
for i := 0 to high(buf) do
buf[i] := (i+13)*7 mod 256;
Writeln(gethash(PByteArray(buf), Length(buf), 17));
end;
begin
Main;
Readln;
end.
这在每个操作系统上产生相同的输出,并且在由32位或64位编译器编译时产生相同的输出。虽然这并不能证明每种可能的输入都是如此,但它会为您提供一个试验台。您可以用自己的输入替换我的输入,如果我是对的,您将发现输出将始终相同,用于固定输入。
对于您的问题,一个合理的解释是您正在读取超出缓冲区的末尾,因此散列错误定义的输入数据。也许使用不同的操作系统或编译器,错误定义的输入数据会有所不同。