| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- unit SHA256;
- {
- SHA256.pas: System.Hash.pas wrapper in the style of the old versions of MD5.pas and SHA1.pas
- Author: Martijn Laan
- License for SHA256.pas: Public domain, no copyright claimed
- }
- interface
- uses
- System.Hash;
- type
- TSHA256Context = record
- hash: THashSHA2;
- end;
- TSHA256Digest = array[0..31] of Byte;
- procedure SHA256Init(var ctx: TSHA256Context);
- procedure SHA256Update(var ctx: TSHA256Context; const buffer; len: Cardinal);
- function SHA256Final(var ctx: TSHA256Context): TSHA256Digest;
- function SHA256Buf(const Buffer; Len: Cardinal): TSHA256Digest;
- function SHA256DigestsEqual(const A, B: TSHA256Digest): Boolean;
- function SHA256DigestToString(const D: TSHA256Digest): String;
- function SHA256DigestFromString(const S: String): TSHA256Digest;
- implementation
- uses
- System.SysUtils;
- procedure SHA256Init(var ctx: TSHA256Context);
- begin
- ctx.hash := THashSHA2.Create(THashSHA2.TSHA2Version.SHA256);
- end;
- procedure SHA256Update(var ctx: TSHA256Context; const buffer; len: Cardinal);
- begin
- ctx.hash.Update(buffer, len);
- end;
- function SHA256Final(var ctx: TSHA256Context): TSHA256Digest;
- begin
- var HashAsBytes := ctx.hash.HashAsBytes;
- Move(HashAsBytes[0], Result[0], SizeOf(Result));
- end;
- function SHA256Buf(const Buffer; Len: Cardinal): TSHA256Digest;
- var
- Context: TSHA256Context;
- begin
- SHA256Init(Context);
- SHA256Update(Context, Buffer, Len);
- Result := SHA256Final(Context);
- end;
- function SHA256DigestsEqual(const A, B: TSHA256Digest): Boolean;
- var
- I: Integer;
- begin
- for I := Low(TSHA256Digest) to High(TSHA256Digest) do
- if A[I] <> B[I] then begin
- Result := False;
- Exit;
- end;
- Result := True;
- end;
- function SHA256DigestToString(const D: TSHA256Digest): String;
- const
- Digits: array[0..15] of Char = '0123456789abcdef';
- var
- Buf: array[0..63] of Char;
- P: PChar;
- I: Integer;
- begin
- P := @Buf[0];
- for I := 0 to 31 do begin
- P^ := Digits[D[I] shr 4];
- Inc(P);
- P^ := Digits[D[I] and 15];
- Inc(P);
- end;
- SetString(Result, Buf, 64);
- end;
- function SHA256DigestFromString(const S: String): TSHA256Digest;
- begin
- if Length(S) <> 64 then
- raise EConvertError.Create('Invalid string length');
- for var I := 0 to 63 do begin
- var B: Byte;
- const C = UpCase(S.Chars[I]);
- case C of
- '0'..'9': B := Byte(Ord(C) - Ord('0'));
- 'A'..'F': B := Byte(Ord(C) - (Ord('A') - 10));
- else
- raise EConvertError.Create('Invalid digit character');
- end;
- const ResultIndex = I shr 1;
- if not Odd(I) then
- Result[ResultIndex] := Byte(B shl 4)
- else
- Result[ResultIndex] := Result[ResultIndex] or B;
- end;
- end;
- end.
|