📄 dechash.pas
字号:
class function TDECHash.CalcStream(const Stream: TStream; Size: Int64; Format: TDECFormatClass; const Progress: IDECProgress): Binary;
var
Buffer: Binary;
Bytes: Integer;
Min,Max,Pos: Int64;
begin
Min := 0;
Max := 0;
with Create do
try
Init;
if StreamBufferSize <= 0 then StreamBufferSize := 8192;
if Size < 0 then
begin
Stream.Position := 0;
Size := Stream.Size;
Pos := 0;
end else Pos := Stream.Position;
Bytes := StreamBufferSize mod FBufferSize;
if Bytes = 0 then Bytes := StreamBufferSize
else Bytes := StreamBufferSize + FBufferSize - Bytes;
if Bytes > Size then SetLength(Buffer, Size)
else SetLength(Buffer, Bytes);
Min := Pos;
Max := Pos + Size;
while Size > 0 do
begin
if Assigned(Progress) then Progress.Process(Min, Max, Pos);
Bytes := Length(Buffer);
if Bytes > Size then Bytes := Size;
Stream.ReadBuffer(Buffer[1], Bytes);
Calc(Buffer[1], Bytes);
Dec(Size, Bytes);
Inc(Pos, Bytes);
end;
Done;
Result := DigestStr(Format);
finally
Free;
ProtectBinary(Buffer);
if Assigned(Progress) then Progress.Process(Min, Max, Max);
end;
end;
class function TDECHash.CalcBinary(const Data: Binary; Format: TDECFormatClass): Binary;
begin
Result := CalcBuffer(Data[1], Length(Data), Format);
end;
class function TDECHash.CalcFile(const FileName: String; Format: TDECFormatClass; const Progress: IDECProgress): Binary;
var
S: TFileStream;
begin
S := TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone);
try
Result := CalcStream(S, S.Size, Format, Progress);
finally
S.Free;
end;
end;
class function TDECHash.CalcBuffer(const Buffer; BufferSize: Integer; Format: TDECFormatClass): Binary;
begin
with Create do
try
Init;
Calc(Buffer, BufferSize);
Done;
Result := DigestStr(Format);
finally
Free;
end;
end;
class function TDECHash.MGF1(const Data; DataSize, MaskSize: Integer; Format: TDECFormatClass = nil): Binary;
// indexed Mask generation function, IEEE P1363 Working Group
// equal to KDF2 except without Seed
begin
Result := KDF2(Data, DataSize, EmptyStr[1], 0, MaskSize, Format);
end;
class function TDECHash.MGF1(const Data: Binary; MaskSize: Integer; Format: TDECFormatClass = nil): Binary;
begin
Result := KDF2(Data, Length(Data), EmptyStr[1], 0, MaskSize, Format);
end;
class function TDECHash.KDF2(const Data; DataSize: Integer; const Seed; SeedSize, MaskSize: Integer; Format: TDECFormatClass = nil): Binary;
// Key Generation Function 2, IEEE P1363 Working Group
var
I,Rounds,DigestBytes: Integer;
Dest: PByteArray;
Count: LongWord;
begin
DigestBytes := DigestSize;
Assert(MaskSize >= 0);
Assert(DataSize >= 0);
Assert(SeedSize >= 0);
Assert(DigestBytes >= 0);
with Create do
try
Rounds := (MaskSize + DigestBytes -1) div DigestBytes;
SetLength(Result, Rounds * DigestBytes);
Dest := @Result[1];
for I := 0 to Rounds -1 do
begin
Count := SwapLong(I);
Init;
Calc(Data, DataSize);
Calc(Count, SizeOf(Count));
Calc(Seed, SeedSize);
Done;
Move(Digest[0], Dest[I * DigestBytes], DigestBytes);
end;
finally
Free;
end;
SetLength(Result, MaskSize);
Result := ValidFormat(Format).Encode(Result[1], MaskSize);
end;
class function TDECHash.KDF2(const Data, Seed: Binary; MaskSize: Integer; Format: TDECFormatClass = nil): Binary;
begin
Result := KDF2(Data[1], Length(Data), Seed[1], Length(Seed), MaskSize, Format);
end;
class function TDECHash.KDFx(const Data; DataSize: Integer; const Seed; SeedSize, MaskSize: Integer; Format: TDECFormatClass = nil; Index: LongWord = 1): Binary;
// DEC's own KDF, even stronger
var
I,J: Integer;
Count: LongWord;
R: Byte;
begin
Assert(MaskSize >= 0);
Assert(DataSize >= 0);
Assert(SeedSize >= 0);
Assert(DigestSize >= 0);
SetLength(Result, MaskSize);
Index := SwapLong(Index);
with Create do
try
for I := 0 to MaskSize -1 do
begin
Init;
Count := SwapLong(I);
Calc(Count, SizeOf(Count));
Calc(Result[1], I);
Calc(Index, SizeOf(Index));
Count := SwapLong(SeedSize);
Calc(Count, SizeOf(Count));
Calc(Seed, SeedSize);
Count := SwapLong(DataSize);
Calc(Count, SizeOf(Count));
Calc(Data, DataSize);
Done;
R := 0;
for J := 0 to DigestSize -1 do
R := R xor Digest[J];
Result[I +1] := Char(R);
end;
finally
Free;
end;
Result := ValidFormat(Format).Encode(Result[1], MaskSize);
end;
class function TDECHash.KDFx(const Data, Seed: Binary; MaskSize: Integer; Format: TDECFormatClass = nil; Index: LongWord = 1): Binary;
begin
Result := KDFx(Data[1], Length(Data), Seed[1], Length(Seed), MaskSize, Format, Index);
end;
class function TDECHash.MGFx(const Data; DataSize, MaskSize: Integer; Format: TDECFormatClass = nil; Index: LongWord = 1): Binary;
begin
Result := KDFx(Data, DataSize, EmptyStr[1], 0, MaskSize, Format, Index);
end;
class function TDECHash.MGFx(const Data: Binary; MaskSize: Integer; Format: TDECFormatClass = nil; Index: LongWord = 1): Binary;
begin
Result := KDFx(Data[1], Length(Data), EmptyStr[1], 0, MaskSize, Format, Index);
end;
// .THash_MD2
class function THash_MD2.DigestSize: Integer;
begin
Result := 16;
end;
class function THash_MD2.BlockSize: Integer;
begin
Result := 16;
end;
function THash_MD2.Digest: PByteArray;
begin
Result := @FDigest;
end;
{$IFNDEF THash_MD2_asm}
procedure THash_MD2.DoTransform(Buffer: PLongArray);
var
I,J,T: LongWord;
begin
for I := 0 to 3 do
begin
PLongArray(@FDigest[16])[I] := Buffer[I];
PLongArray(@FDigest[32])[I] := PLongArray(@FDigest[0])[I] xor PLongArray(@FDigest[16])[I];
end;
T := FDigest[63];
for I := 0 to 15 do
begin
T := FDigest[I + 48] xor MD2_PISubst[FDigest[I + 16] xor Byte(T)];
FDigest[I + 48] := Byte(T);
end;
T := 0;
for I := 0 to 17 do
begin
for J := 0 to 47 do
begin
T := FDigest[J] xor MD2_PISubst[T];
FDigest[J] := Byte(T);
end;
T := (T + I) and $FF;
end;
end;
{$ENDIF}
procedure THash_MD2.DoInit;
begin
FillChar(FDigest, SizeOf(FDigest), 0);
end;
procedure THash_MD2.DoDone;
var
Remain: Integer;
begin
Remain := FBufferSize - FBufferIndex;
FillChar(FBuffer[FBufferIndex], Remain, Remain);
DoTransform(Pointer(FBuffer));
Move(FDigest[48], FBuffer^, FBufferSize);
DoTransform(Pointer(FBuffer));
end;
// .THashBaseMD4
class function THashBaseMD4.DigestSize: Integer;
begin
Result := 16;
end;
class function THashBaseMD4.BlockSize: Integer;
begin
Result := 64;
end;
function THashBaseMD4.Digest: PByteArray;
begin
Result := @FDigest;
end;
procedure THashBaseMD4.DoInit;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -