提问人:Json Dabbler 提问时间:11/17/2023 最后编辑:Remy LebeauJson Dabbler 更新时间:11/17/2023 访问量:100
Bob Jenkins Hash Without Using Pointers in Delphi [已关闭]
Bob Jenkins Hash without using Pointers in Delphi [closed]
问:
我有在 Delphi 中执行 Bob Jenkins Hash 的代码,但它使用的是指针。如何在不使用指针的情况下编写代码?
有人可以在不使用指针的情况下帮助我处理 Bob Jenkins Hash 吗?
代码:
{$Q-}
unit uBobJenkins;
interface
uses
System.Classes, System.SysUtils;
type
THashBobJenkins = record
private
class function HashLittle(const Data; Len, InitVal: Integer): Integer; static;
public
class function GetHashString(const AString: string): string; static;
end;
implementation
class function THashBobJenkins.HashLittle(const Data; Len, InitVal: Integer): Integer;
function Rot(x, k: Cardinal): Cardinal; inline;
begin
Result := (x shl k) or (x shr (32 - k));
end;
procedure Mix(var a, b, c: Cardinal); inline;
begin
Dec(a, c); a := a xor Rot(c, 4); Inc(c, b);
Dec(b, a); b := b xor Rot(a, 6); Inc(a, c);
Dec(c, b); c := c xor Rot(b, 8); Inc(b, a);
Dec(a, c); a := a xor Rot(c,16); Inc(c, b);
Dec(b, a); b := b xor Rot(a,19); Inc(a, c);
Dec(c, b); c := c xor Rot(b, 4); Inc(b, a);
end;
procedure Final(var a, b, c: Cardinal); inline;
begin
c := c xor b; Dec(c, Rot(b,14));
a := a xor c; Dec(a, Rot(c,11));
b := b xor a; Dec(b, Rot(a,25));
c := c xor b; Dec(c, Rot(b,16));
a := a xor c; Dec(a, Rot(c, 4));
b := b xor a; Dec(b, Rot(a,14));
c := c xor b; Dec(c, Rot(b,24));
end;
{$POINTERMATH ON}
var
pb: PByte;
pd: PCardinal absolute pb;
a, b, c: Cardinal;
label
case_1, case_2, case_3, case_4, case_5, case_6,
case_7, case_8, case_9, case_10, case_11, case_12;
begin
a := Cardinal($DEADBEEF) + Cardinal(Len) + Cardinal(InitVal);
b := a;
c := a;
pb := @Data;
// 4-byte aligned data
if (Cardinal(pb) and 3) = 0 then
begin
while Len > 12 do
begin
Inc(a, pd[0]);
Inc(b, pd[1]);
Inc(c, pd[2]);
Mix(a, b, c);
Dec(Len, 12);
Inc(pd, 3);
end;
case Len of
0: Exit(Integer(c));
1: Inc(a, pd[0] and $FF);
2: Inc(a, pd[0] and $FFFF);
3: Inc(a, pd[0] and $FFFFFF);
4: Inc(a, pd[0]);
5:
begin
Inc(a, pd[0]);
Inc(b, pd[1] and $FF);
end;
6:
begin
Inc(a, pd[0]);
Inc(b, pd[1] and $FFFF);
end;
7:
begin
Inc(a, pd[0]);
Inc(b, pd[1] and $FFFFFF);
end;
8:
begin
Inc(a, pd[0]);
Inc(b, pd[1]);
end;
9:
begin
Inc(a, pd[0]);
Inc(b, pd[1]);
Inc(c, pd[2] and $FF);
end;
10:
begin
Inc(a, pd[0]);
Inc(b, pd[1]);
Inc(c, pd[2] and $FFFF);
end;
11:
begin
Inc(a, pd[0]);
Inc(b, pd[1]);
Inc(c, pd[2] and $FFFFFF);
end;
12:
begin
Inc(a, pd[0]);
Inc(b, pd[1]);
Inc(c, pd[2]);
end;
end;
end
else
begin
// Ignoring rare case of 2-byte aligned data. This handles all other cases.
while Len > 12 do
begin
Inc(a, pb[0] + pb[1] shl 8 + pb[2] shl 16 + pb[3] shl 24);
Inc(b, pb[4] + pb[5] shl 8 + pb[6] shl 16 + pb[7] shl 24);
Inc(c, pb[8] + pb[9] shl 8 + pb[10] shl 16 + pb[11] shl 24);
Mix(a, b, c);
Dec(Len, 12);
Inc(pb, 12);
end;
case Len of
0: Exit(Integer(c));
1: goto case_1;
2: goto case_2;
3: goto case_3;
4: goto case_4;
5: goto case_5;
6: goto case_6;
7: goto case_7;
8: goto case_8;
9: goto case_9;
10: goto case_10;
11: goto case_11;
12: goto case_12;
end;
case_12:
Inc(c, pb[11] shl 24);
case_11:
Inc(c, pb[10] shl 16);
case_10:
Inc(c, pb[9] shl 8);
case_9:
Inc(c, pb[8]);
case_8:
Inc(b, pb[7] shl 24);
case_7:
Inc(b, pb[6] shl 16);
case_6:
Inc(b, pb[5] shl 8);
case_5:
Inc(b, pb[4]);
case_4:
Inc(a, pb[3] shl 24);
case_3:
Inc(a, pb[2] shl 16);
case_2:
Inc(a, pb[1] shl 8);
case_1:
Inc(a, pb[0]);
end;
Final(a, b, c);
Result := Integer(c);
end;
{$POINTERMATH OFF}
class function THashBobJenkins.GetHashString(const AString: string): string;
begin
Result := HashLittle(Pointer(AString)^, Length(AString) * SizeOf(Char), 0).ToHexString(8);
end;
end.
I have tried everything. I have tried using Byte arrays and I do not even remember what I have tried.
答: 暂无答案
评论
const
Cardinal(pb)
NativeUInt(pb)
System.Hash.THashBobJenkins
.