delphi - Implementation of FNV -


i trying implement fnv hash http://isthe.com/chongo/tech/comp/fnv/

i converted powerbasic's inline asm on page 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         dsize := getfilesize(hfile, nil);         if dsize <> 0         begin           setfilepointer(hfile, 0, nil, file_begin);           getmem(result, dsize);           readfile(hfile, result^, dsize, dread, nil);           if dread = 0             messagebox(0, pchar('error reading file.'), pchar('read error'), mb_iconexclamation)          end;         closehandle(hfile);     end;      function getpointersize(lpbuffer: pointer): cardinal; // function erazerz     begin       if lpbuffer = nil         result := cardinal(-1)       else         result := cardinal(pointer(cardinal(lpbuffer) -4)^) , $7ffffffc -4;     end;       function fnv32( dwoffset : pointer; dwlen : dword; offset_basis : dword) : dword ;       asm      mov esi, dwoffset      //;esi = ptr buffer      mov ecx, dwlen         //;ecx = length of buffer (counter)      mov eax, offset_basis  //;set 2166136261 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 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 0, jmp 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; 

if size of given file more 200kb, output random (hash) number. missing something?

your asm code buggy, imho. crash application, written.

  • you need preseve esi/edi/ebx registers
  • parameters passed in eax,ecx,edx registers
  • result eax register

correct way (not tested, written here there):

function fnv32(dwoffset : pointer; dwlen : dword; offset_basis: dword) : dword ; asm // eax=dwoffset ecx=dwlen edx=offset_basis -> result in eax   push esi   push edi   mov esi,eax   mov eax,edx   or ecx,ecx   je @z   mov edi,16777619   xor edx,edx @1:   mul edi   mov dl,[esi]   xor eax,edx   inc esi   dec ecx   jnz @1 @z:   pop edi   pop esi end; 

so read , hash file, in pure delphi way (don't use windows api did):

function fnv32file(const afilename: tfilename): dword; begin   tmemorystream.create   try     loadfromfile(afilename);     result := fnv32(memory,size,0);       free;   end; end; 

a pure pascal version won't slower imho (the bottleneck definitively reading data hard drive):

function fnv32(dwoffset : pbytearray; dwlen : dword; offset_basis: dword): dword ; var i: integer; begin   result := offset_basis;   := 0 dwlen-1     result := (result*16777619) xor dword(dwoffset^[i]); end; 

Comments

Popular posts from this blog

android - Spacing between the stars of a rating bar? -

aspxgridview - Devexpress grid - header filter does not work if column is initially hidden -

c# - How to execute a particular part of code asynchronously in a class -