IRsoft - Software and more by Ingmar Runge

MD5 in Delphi

This is a lightweight implementation of the MD5 checksum algorithm in Delphi. It uses Windows' Crypto API.

You need the Crypto API headers for Delphi from http://jedi-apilib.sourceforge.net/ (Interface for Microsoft CryptoAPI version 2.0). Add Wcrypt2 to your uses clause. As the home page seems to have changed, you can now also get the file from http://stuff.irsoft.de/CryptoAPI2.zip.

function md5(const Input: String): String;
var
  hCryptProvider: HCRYPTPROV;
  hHash: HCRYPTHASH;
  bHash: array[0..$7f] of Byte;
  dwHashBytes: Cardinal;
  pbContent: PByte;
  i: Integer;

begin
  dwHashBytes := 16;
  pbContent := Pointer(PChar(Input));

  Result := '';

  if CryptAcquireContext(@hCryptProvider, nil, nil, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT or CRYPT_MACHINE_KEYSET) then
  begin
    if CryptCreateHash(hCryptProvider, CALG_MD5, 0, 0, @hHash) then
    begin
      if CryptHashData(hHash, pbContent, Length(Input) * sizeof(Char), 0) then
      begin
        if CryptGetHashParam(hHash, HP_HASHVAL, @bHash[0], @dwHashBytes, 0) then
        begin
          for i := 0 to dwHashBytes - 1 do
          begin
            Result := Result + Format('%.2x', [bHash[i]]);
          end;
        end;
      end;
      CryptDestroyHash(hHash);
    end;

    CryptReleaseContext(hCryptProvider, 0);
  end;

  Result := AnsiLowerCase(Result);
end;
Parsed in 0.025 seconds, using GeSHi © 2005 Nigel McNie

Examples: md5('') returns d41d8cd98f00b204e9800998ecf8427e. md5('test') returns 098f6bcd4621d373cade4e832627b4f6, if 'test' are four plain bytes and c8059e2ec7419f590e79d7f1b774bfe6 if it's a unicode string. Yes, this can be confusing.

The code also works in Delphi 2009 without modifications. Please be aware that MD5 operates on bytes, though, so, as seen above, md5('test') will return two different hashes. To avoid this, you can e.g. use platform independent UTF-8 encoded strings and the UTF8String type in Delphi.

Last edited by Ingmar on Thursday, March 5th 2009 03:16:46 CET