Environment: Win7 64bit, Delphi 2010, Win32 project.
I try to get integer hash values for set of strings with the help of BobJenkinsHash() function from Generics.Defaults.
It works but some points are not clear for me.
As I see on source site it is used uint32_t as result type of the hashword() function:
uint32_t hashword(
const uint32_t *k, /* the key, an array of uint32_t values */
size_t length, /* the length of the key, in uint32_ts */
uint32_t initval) /* the previous hash, or an arbitrary value */
{
Is it unsigned int?
Second question is I have different results for different strings with identical values:
'DEFPROD001' => 759009858
'DEFPROD001' => 1185633302
Is it normal behaviour?
My full function to calculate hash (if first argument is empty then second is returned):
function TAmWriterJD.ComposeID(const defaultID: string; const GUID: String): String;
var
bjh: Integer;
begin
if defaultID = '' then
begin
Result := GUID
end
else
begin
bjh := BobJenkinsHash(defaultID, Length(defaultID) * SizeOf(defaultID), 0);
Result := IntToStr(bjh);
end;
end;
The Delphi implementation is declared like so:
function BobJenkinsHash(const Data; Len, InitData: Integer): Integer;
It returns a signed 32 bit integer. So yes, this implementation can return negative values.
The C implementation you refer to returns an unsigned 32 bit integer. So that cannot return negative values.
Assuming both implementations are correct then they will, given the same input, return the same 32 bits of output. It's just that when interpreted as signed or unsigned values these bits have different meaning.
As to your second question, passing the same string to the hash function will yield the same hash. You must have made a mistake in your test case.
BobJenkinsHash(defaultID, Length(defaultID) * SizeOf(defaultID), 0);
Here defaultID
is a string
variable and that is implemented as a pointer. You are therefore hashing the address. And not even doing that correctly due to your incorrect length argument. Instead you need to write:
BobJenkinsHash(Pointer(defaultID)^, Length(defaultID) * SizeOf(Char), 0);
This program demonstrates:
{$APPTYPE CONSOLE}
uses
System.Generics.Defaults;
var
s, t: string;
begin
s := 'DEFPROD001';
t := 'DEFPROD001';
Writeln(BobJenkinsHash(s, Length(s) * SizeOf(s), 0));
Writeln(BobJenkinsHash(t, Length(t) * SizeOf(t), 0));
Writeln(BobJenkinsHash(Pointer(s)^, Length(s) * SizeOf(Char), 0));
Writeln(BobJenkinsHash(Pointer(t)^, Length(t) * SizeOf(Char), 0));
Readln;
end.
Output:
2129045826 -331457644 -161666357 -161666357
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With