Simple and Fast Hash Functions in Delphi


A Hash function returns a 32-bit (or sometimes 64-bit) integers for any given length of data. The function has to be as fast as possible and the collision should be as less as possible.

In Delphi, you can have a Hash function defined as follows, which takes a pointer and a length, and returns a 32-bit unsigned (or signed) integer.

type
  HashFunction = function(AData: Pointer; ADataLength: Integer): Cardinal;

Hash_djb2

function Hash_djb2(AData: Pointer; ADataLength: Integer): Cardinal;
var
  i: integer;
begin
  Result := 5381;
  for i := 1 to ADataLength do
  begin
    Result := ((Result shl 5) + Result) + PByte(AData)^;
    AData  := Pointer(NativeUInt(AData) + 1);
  end;
end;

Hash_djb2a

A Slight variation of Hash_djb2

function Hash_djb2a(AData: Pointer; ADataLength: Integer): Cardinal;
var
  i: integer;
begin
  Result := 5381;
  for i := 1 to ADataLength do
  begin
    Result := ((Result shl 5) xor Result) xor PByte(AData)^;
    AData  := Pointer(NativeUInt(AData) + 1);
  end;
end;

Hash_fnv

Hash_fnv(AData: Pointer; ADataLength: Integer): Cardinal;
var
  i: integer;
begin
  Result := 2166136261;
  for i := 1 to ADataLength do
  begin
    Result := (Result * 16777619) xor PByte(AData)^;
    AData  := Pointer(NativeUInt(AData) + 1);
  end;
end;

Hash_fnv1a

Slight variation of Hash_fnv.

function Hash_fnv1a(AData: Pointer; ADataLength: Integer): Cardinal;
var
  i: integer;
begin
  Result := 2166136261;
  for i := 1 to ADataLength do
  begin
    Result := (Result xor PByte(AData)^) * 16777619;
    AData  := Pointer(NativeUInt(AData) + 1);
  end;
end;

Hash_sdbm

function Hash_sdbm(AData: Pointer; ADataLength: Integer): Cardinal;
var
  i: integer;
begin
  Result := 0;
  for i := 1 to ADataLength do
  begin
    Result := PByte(AData)^ + (Result shl 6) + (Result shl 16) - Result;
    AData  := Pointer(NativeUInt(AData) + 1);
  end;
end;

Hash_jenkis

function Hash_jenkis(AData: Pointer; ADataLength: Integer): Cardinal;
var
  i: integer;
begin
  Result := 0;
  for i := 1 to ADataLength do
  begin
    Inc(Result, PByte(AData)^);
    Inc(Result, Result shl 10);
    Result := Result xor (Result shr 6);
    AData  := Pointer(NativeUInt(AData) + 1);
  end;
  Inc(Result, Result shl 3);
  Result := Result xor (Result shr 11);
  Inc(Result, Result shl 15);
end;

At D2007, the size of NativeUInt is incorrectly defined as 8 bytes, thus

{$if CompilerVersion <= 18.5}
  NativeInt = Integer;
  NativeUInt = Cardinal;
{$ifend}

should allow the above 6 hash functions to be compilable under both 32-bit and 64-bit Delphi.

–EOF (The Ultimate Computing & Technology Blog) —

GD Star Rating
loading...
459 words
Last Post: C# Randomness Using GUID
Next Post: Does Parallel.For in Delphi Actually Improve the Performance?

The Permanent URL is: Simple and Fast Hash Functions in Delphi

Leave a Reply