📄 shaunit.~pas
字号:
unit SHAUnit;
interface
type
PSHACtx = ^TSHACtx;
TSHACtx = record
state: array[0..7] of LongWord;
length, curlen: Int64;
buf: array[0..63] of Byte;
end;
procedure SHAInit(var md: TSHACtx);
procedure SHAUpdate(var md: TSHACtx; buf: Pointer; len: Int64; sz: Word);
function SHAFinal(var md: TSHACtx; sz: Word): String;
implementation
const
HexChars: array[0..15] of Char = ('0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', 'a', 'b',
'c', 'd', 'e', 'f');
//整数转换成16进制
function IntToHex(Int: Int64; IntSize: Byte): String;
var
n: Byte;
begin
Result := '';
for n := 0 to IntSize - 1 do
begin
Result := HexChars[Int and $F] + Result;
Int := Int shr $4;
end;
end;
function ror(x: LongWord; y: Byte): LongWord; assembler;
asm
mov cl,dl
ror eax,cl
end;
function rol(x: LongWord; y: Byte): LongWord; assembler;
asm
mov cl,dl
rol eax,cl
end;
function Endian(X: LongWord): LongWord;
asm
bswap eax
end;
function ft1(t: Byte; x, y, z: LongWord): LongWord;
begin
case t of
0..19: Result := (x and y) or ((not x) and z);
20..39: Result := x xor y xor z;
40..59: Result := (x and y) or (x and z) or (y and z);
else
Result := x xor y xor z;
end;
end;
//四个常数
function Kt1(t: Byte): LongWord;
begin
case t of
0..19: Result := $5a827999;
20..39: Result := $6ed9eba1;
40..59: Result := $8f1bbcdc;
else
Result := $ca62c1d6
end;
end;
procedure SHACompress(var md: TSHACtx);
var
S: array[0..4] of LongWord;
W: array[0..79] of LongWord;
i, t: LongWord;
begin
Move(md.state, S, SizeOf(S));
for i := 0 to 15 do
W[i] := Endian(PLongWord(LongWord(@md.buf) + i * 4)^);
for i := 16 to 79 do
W[i] := rol(W[i - 3] xor W[i - 8] xor W[i - 14] xor W[i - 16], 1);
for i := 0 to 79 do
begin
t := rol(S[0], 5) + ft1(i, S[1], S[2], S[3]) + S[4] + Kt1(i) + W[i];
S[4] := S[3];
S[3] := S[2];
S[2] := rol(S[1], 30);
S[1] := S[0];
S[0] := t;
end;
for i := 0 to 4 do
md.state[i] := md.state[i] + S[i];
end;
//五个32位变量
procedure SHAInit(var md: TSHACtx);
begin
md.curlen := 0; md.length := 0;
md.state[0] := $67452301;
md.state[1] := $efcdab89;
md.state[2] := $98badcfe;
md.state[3] := $10325476;
md.state[4] := $c3d2e1f0;
end;
procedure SHAUpdate(var md: TSHACtx; buf: Pointer; len: Int64; sz: Word);
begin
while (len > 0) do
begin
md.buf[md.curlen] := PByte(buf)^;
md.curlen := md.curlen + 1;
buf := Ptr(LongWord(buf) + 1);
if (md.curlen = 64) then
begin
SHACompress(md);
md.length := md.length + 512;
md.curlen := 0;
end;
Dec(len);
end;
end;
function SHAFinal(var md: TSHACtx; sz: Word): String;
var
i: LongWord;
begin
md.length := md.length + md.curlen shl 3;
md.buf[md.curlen] := $80;
md.curlen := md.curlen + 1;
if (md.curlen > 56) then
begin
while md.curlen < 64 do
begin
md.buf[md.curlen] := 0;
md.curlen := md.curlen + 1;
end;
SHACompress(md);
md.curlen := 0;
end;
while md.curlen < 56 do
begin
md.buf[md.curlen] := 0;
md.curlen := md.curlen + 1;
end;
for i := 56 to 63 do
md.buf[i] := (md.length shr ((63 - i) * 8)) and $FF;
SHACompress(md);
Result := '';
for i := 0 to 4 do
Result := Result + IntToHex(md.state[i], 8);
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -