SHA1 hashing in Delphi XE?

Leonardo, I think which your problem is the UNICODE when you uses a function to hash a string you are passing a array (buffer) of bytes. So when you pass the abc string in Delphi XE, your are hashing a buffer like this 61 00 62 00 63 00 (Hex representation).

Leonardo, I think which your problem is the UNICODE when you uses a function to hash a string you are passing a array (buffer) of bytes. So when you pass the abc string in Delphi XE, your are hashing a buffer like this 61 00 62 00 63 00 (Hex representation) check this sample application which uses the Windows crypto functions from the Jwscl library (JEDI Windows Security Code Lib) program Jwscl_TestHash; {$APPTYPE CONSOLE} uses JwsclTypes, JwsclCryptProvider, Classes, SysUtils; function GetHashString(Algorithm: TJwHashAlgorithm; Buffer : Pointer;Size:Integer) : AnsiString; var Hash: TJwHash; HashSize: Cardinal; HashData: Pointer; I : Integer; begin Hash := TJwHash. Create(Algorithm); try Hash.

HashData(Buffer,Size); HashData := Hash. RetrieveHash(HashSize); try SetLength(Result,HashSize*2); BinToHex(PAnsiChar(HashData),PAnsiChar(Result),HashSize); finally TJwHash. FreeBuffer(HashData); end; finally Hash.

Free; end; end; function GetHashSHA(FBuffer : AnsiString): AnsiString; begin Result:=GetHashString(haSHA,@FBuffer1,Length(FBuffer)); end; function GetHashSHA_Unicode(FBuffer : String): String; begin Result:=GetHashString(haSHA,@FBuffer1,Length(FBuffer)*SizeOf(Char)); end; begin try Writeln(GetHashSHA('abc')); Writeln(GetHashSHA('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq')); Writeln(GetHashSHA_Unicode('abc')); Writeln(GetHashSHA_Unicode('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq')); Readln; except on E:Exception do begin Writeln(E. Classname, ':', E. Message); Readln; end; end; end.

This return abc AnsiString A9993E364706816ABA3E25717850C26C9CD0D89D abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq AnsiString 84983E441C3BD26EBAAE4AA1F95129E5E54670F1 for abc unicode 9F04F41A848514162050E3D68C1A7ABB441DC2B5 abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq Unicode 51D7D8769AC72C409C5B0E3F69C60ADC9A039014.

Great answer. I see now. I guess what tipped me off in the wrong direction was the DCPCrypt2 SelfTest function, which returns false.

– Leonardo Herrera Feb 8 at 13:22 Good tip. I didn't know you could use the crypto libs in Windows, using JWSCL wrappers. – Warren P Feb 8 at 14:02 This source code can be compiled with Delphi 7?

– Clóvis Valadares Junior Mar 18 at 17:20.

My Cygwin command-prompt tells me it is indeed Unicode that's confusing you: ~$ printf 'a\0b\0c\0' | sha1sum 9f04f41a848514162050e3d68c1a7abb441dc2b5 *- ~$ printf 'abc' | sha1sum a9993e364706816aba3e25717850c26c9cd0d89d.

Wow. This is just great. – Leonardo Herrera Feb 8 at 13:18 1 @Leonardo I expect you're being sarcastic, but it does show the utility of Cygwin for testing these kinds of hypotheses - md5sum, sha1sum, and openssl for a lot more.

– Barry Kelly Feb 8 at 15:05 No, I'm not being sarcastic at all! I accepted RRUZ's answer because it is more complete, but this is a terrific answer. Thanks!

– Leonardo Herrera Feb 8 at 17:15 I wouldn't have said it was more complete, it's just more verbose which isn't necessarily better. Anyway, I'm not trying to knock RRUZ, but I'm with Barry, all good developers should learn to use powerful command line tools so that they can get tasks like this done more efficiently. – David Heffernan Feb 9 at 15:26 I agree completely re: different tools.

I loved this answer, it was really clear, and actually I read this before reading RRUZ's and got the answer immediatly. If I could accept two answers for one question I would! (RRUZ answer is not just more verbose.) – Leonardo Herrera Feb 9 at 20:43.

Apparently, that's the case. – Leonardo Herrera Feb 8 at 13:24.

Okay, so it was Unicode issues. Just in case you want to know, this is my Unit1. Pas source.

You need a form with a memo and a button. Requires DCPCrypt2, LockBox2, LockBox3 and the Hashes unit. Unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, LbCipher, LbClass, StdCtrls, DCPcrypt2, DCPsha1, Hashes, uTPLb_CryptographicLibrary, uTPLb_BaseNonVisualComponent, uTPLb_Hash; type THashProc = reference to procedure(src: AnsiString; var output: AnsiString); TForm1 = class(TForm) Memo1: TMemo; btnTest: TButton; function Display(Buf: TBytes): String; procedure LockBox2Test; procedure LockBox3Test; procedure DCPCrypto2Test; procedure HashesTest; procedure btnTestClick(Sender: TObject); private { Private declarations } procedure RunTests(Name: String; HashFunc: THashProc); public { Public declarations } end; var Form1: TForm1; implementation uses uTPLb_StreamUtils; {$R *.

Dfm} procedure TForm1. BtnTestClick(Sender: TObject); begin LockBox2Test; LockBox3Test; DCPCrypto2Test; HashesTest; end; procedure TForm1. DCPCrypto2Test; begin RunTests('DCPCrypto2', procedure(src: AnsiString; var output: AnsiString) var Digest: TSHA1Digest; Bytes : TBytes; SHA1 : TDCP_sha1; begin SHA1 := TDCP_sha1.

Create(nil); SHA1. Init; SHA1. UpdateStr(src); SHA1.

Final(Digest); SHA1. Destroy; SetLength(Bytes, 20); Move(Digest, Bytes0, 20); output := Form1. Display(Bytes); end); end; function TForm1.

Display(Buf: TBytes): String; var i: Integer; begin Result := ''; for I := 0 to 19 do Result := Result + Format('%0.2x', Bufi); Result := LowerCase(Trim(Result)); end; procedure TForm1. HashesTest; begin RunTests('Hashes', procedure(src: AnsiString; var output: AnsiString) begin output := CalcHash2(src, haSHA1) end) end; procedure TForm1. LockBox2Test; begin RunTests('LockBox2', procedure(src: AnsiString; var output: AnsiString) var Digest: TSHA1Digest; Bytes : TBytes; SHA1 : TLbSHA1; begin SHA1 := TLbSHA1.

Create(nil); SHA1. HashStringA(src); SHA1. GetDigest(Digest); SHA1.

Destroy; SetLength(Bytes, 20); Move(Digest, Bytes0, 20); output := Form1. Display(Bytes); end); end; procedure TForm1. LockBox3Test; begin RunTests('LockBox3', procedure(src: AnsiString; var output: AnsiString) var Digest: TSHA1Digest; bytes : TBytes; P, Sz: integer; aByte: byte; s: string; SHA1 : THash; Lib : TCryptographicLibrary; begin Lib := TCryptographicLibrary.

Create(nil); SHA1 := THash. Create(nil); SHA1. CryptoLibrary := Lib; SHA1.

HashId := 'native.hash. SHA-1'; SHA1. Begin_Hash; SHA1.

HashAnsiString(src); if not assigned(SHA1. HashOutputValue) then output := 'nil' else begin SetLength(Bytes, 20); Sz := SHA1.HashOutputValue. Size; if Sz 20 then output := Format('wrong size: %d', Sz) else begin P := 0; SHA1.HashOutputValue.

Position := 0; while SHA1.HashOutputValue. Read(aByte, 1) = 1 do begin bytesP := aByte; Inc(P); end; output := Form1. Display(Bytes); end; end; SHA1.

Destroy; Lib. Destroy; end) end; procedure TForm1. RunTests(Name: String; HashFunc: THashProc); var i: Integer; Tests: array 1 .. 2, 1 .. 2 of AnsiString; src, res: AnsiString; expected: String; begin // http://www.nsrl.nist.gov/testdata/ Tests11 := 'abc'; Tests12 := 'a9993e364706816aba3e25717850c26c9cd0d89d'; Tests21 := 'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'; Tests22 := '84983e441c3bd26ebaae4aa1f95129e5e54670f1'; Memo1.Lines.

Add(''); Memo1.Lines. Add('**' + Name + '**'); Memo1.Lines. Add(''); for I := 1 to 2 do begin src := Testsi1; expected := Testsi2; HashFunc(src, res); res := Trim(LowerCase(res)); if res = expected then begin Memo1.Lines.

Add(Format(' Test %d passes', i)) end else begin Memo1.Lines. Add(Format(' FAILED: %d (''%s'') ', i, src)); Memo1.Lines. Add(Format(' Got: ''%s''', res)); Memo1.Lines.

Add(Format(' Expected: ''%s''', expected)); end; end; end; end.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions