-1

I use FNV to hash a file in my 32 bit OS. Why the hash result of same code is different if I use the code in 64 bit OS?

Here's my code:

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;
Sir Rufo
  • 18,395
  • 2
  • 39
  • 73
alycia
  • 59
  • 1
  • 8

1 Answers1

1

This code will produce the same output irrespective of the bitness of the operating system. Furthermore the output is independent of the bitness of the process. That is, if you compile for 32 bit and 64 bit, the output will be the same.

The logical conclusion therefore, is that the different output is caused by supplying different input.

One might ask why you have a swallow all exception handler in your code. That must be a really bad idea. If you supply incorrect parameters which lead to an access violation, you'll never find out. I urge you to remove that exception handler.


To demonstrate my point, I offer the following simple test program:

{$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.

This produces the same output on every operating system, and the same output when compiled by either the 32 bit or 64 bit compiler. Whilst this does not prove that will be the case for every possible input, it gives you a test bed. You can replace my input with your own and you will discover, if I am right, that the output will always be the same, for fixed input.


One plausible explanation for your problem is that you are reading beyond the end of the buffer and so hashing ill-defined input data. And perhaps with a different OS or compiler, that ill-defined input data differs.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • How to make the output same if I only compile for 32 bit? I have changed all DWORD to Int64, the result is still different. – alycia Aug 14 '14 at 09:22
  • I have tried to compile for 64 bit and the result is still different. I believe you have answered this problem in your additional answers. However, it is quite impossible for me to change the code or even compile all my codes for 64 bit. Is there any hack for my broken 32 bit program so it can make same output in 64 bit? hack? – alycia Aug 14 '14 at 09:44
  • I suggest you read the answer again. That code produces the same output, given the same input, when run on 32/64 bit OS, when compiled for 32/64 bit processes. Changing DWORD to Int64 would completely change the meaning of the code. Don't do that. And the question talks about 64 bit OS, but you also talk about compiling for 64 bit process. Which is it? 32/64 OS, or 32/64 bit process? – David Heffernan Aug 14 '14 at 09:48
  • 1
    I deleted my earlier comments, and reverted my answer to its original form. Those comments, and my answer update were nonsense. – David Heffernan Aug 14 '14 at 09:52
  • I used to compile my program with Target Platform is 32-bit Windows in Windows 7 32 bit. The code is used to produces hash of many files. Problem is I don't have those files again therefore I prefer not to change my hash function. I try my program in Windows 7 64 bit and it produces different result. I don't want to compile my program for 64-bit Windows as Target Platform. Any hack? – alycia Aug 14 '14 at 09:59
  • Please stop asking for hacks and please start trying to understand what is going on. I am confident that, given the same input, the code always produces the same output. Can you prove me wrong? – David Heffernan Aug 14 '14 at 10:00
  • Okay, you're right. I have proven your code. Probably the problem is the input data that taken from some part of executable. – alycia Aug 14 '14 at 10:28
  • Input data taken from running executable? That is certainly subject to change on different systems. – David Heffernan Aug 14 '14 at 10:29
  • There was a problem in the input data. I have solved my problem because of your answers. Thanks. – alycia Aug 15 '14 at 01:41