FNV哈希在64位操作系统中产生不同的结果

时间:2014-08-14 08:39:47

标签: delphi delphi-xe2 fnv

我使用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;

1 个答案:

答案 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位编译器编译时产生相同的输出。虽然这并不能证明每种可能的输入都是如此,但它会为您提供一个试验台。您可以用自己的输入替换我的输入,如果我是对的,您将发现输出将始终相同,用于固定输入。


对于您的问题,一个合理的解释是您正在读取超出缓冲区的末尾,因此散列错误定义的输入数据。也许使用不同的操作系统或编译器,错误定义的输入数据会有所不同。