Welcome to the new DelphiDabbler Code Library Documentation.

This is a new site that's currently running on alpha code. There are going to be bugs. If you discover any, please report them on the site's issues page (GitHub account required). Thanks.

Warning: Many URLs are going to change. Refer to the README file to discover which library project's documentation has been completed.

MD5 How-to: How To Get Raw Digest Data

Applies to: ~>1.0

An MD5 digest or hash is an 8 byte value. Most of the time all you need to do with a hash is display it or compare it to another hash. But occasionally you need to access the data itself.

TPJMD5Digest provides two views of the digest data:

Long word access

This is the most common way to interpret MD5 digest data. For example if you are transmitting the MD5 hash via an HTTP header you encode the data based on the long words.

There are several ways of accessing the hash as long words. The most useful are:

  1. By directly indexing a TPJMD5Digest variable. (This is made possible by the TPJMD5Digest.Parts default array property).
  2. By accessing the elements of the LongWords array.
  3. By accessing named long word variables A, B, C and D.

For a TPJMD5Digest variable D, the following are equivalent:

D.A = D[0] = D.LongWords[0]
D.B = D[1] = D.LongWords[1]
D.C = D[2] = D.LongWords[2]
D.D = D[3] = D.LongWords[3]

Long word examples

Use direct indexing like this:

var
  D: TPJMD5Digest;
  Idx: Integer;
begin
  D := TPJMD5.Calculate('Foo', TEncoding.ASCII);
  for Idx := 0 to 3 do
    ShowMessageFmt('D[%d] = %.8X', [Idx, D[Idx]]);
end;

Iterate the long words of the digest using the LongWords array field like this:

var
  D: TPJMD5Digest;
  LW: LongWord;
begin
  D := TPJMD5.Calculate('Foo', TEncoding.ASCII);
  for LW in D.LongWords do
    ShowMessage(IntToHex(LW, 8));
end;

Access the long words by name like this:

var
  D: TPJMD5Digest;
begin
  D := TPJMD5.Calculate('Foo', TEncoding.ASCII);
  ShowMessageFmt('A=%.8X  B=%.8X  C=%.8X  D=%.8X', [D.A, D.B, D.C, D.D]);
end;

Byte access

It is sometimes convenient to access the digest data as individual bytes. You may want access a byte at a time or you may want a copy of the whole digest. TPJMD5Digest provides both

Byte by byte access is provided via the Bytes array field. This can be indexed from 0 to 15 or it can be iterated.

Digest data can be copied to a TBytes array by means of an implicit cast: you just assign a TPJMD5Digest variable to a TBytes variable which receives a copy of the 16 bytes of the digest’s data.

Byte examples

Iterate the Bytes array field like this:

var
  D: TPJMD5Digest;
  B: Byte;
  SL: TStrings;
begin
  D := TPJMD5.Calculate('Foo', TEncoding.ASCII);
  SL := TStringList.Create;
  try
    for B in D.Bytes do
      SL.Add(IntToStr(B));
    ShowMessage('D.Bytes = (' + SL.DelimitedText + ')');
  finally
    SL.Free;
  end;
end;

Access the Bytes field by index like this:

var
  D: TPJMD5Digest;
  Idx: Integer;
  S: string;
begin
  D := TPJMD5.Calculate('Foo', TEncoding.ASCII);
  S := '';
  for Idx := Low(D.Bytes) to High(D.Bytes) do
    S := S + Format('D.Bytes[%d] = %d'#10, [Idx, D.Bytes[Idx]]);
  ShowMessage(S);
end;

Copy the data to a TBytes array like this:

var
  D: TPJMD5Digest;
  S: string;
  BA: TBytes;
  B: Byte;
begin
  D := TPJMD5.Calculate('Foo', TEncoding.ASCII);
  BA := D; // assignment uses implicit cast of TPJMD5Digest to TBytes
  S := '';
  for B in BA do
    S := S + '  ' + IntToStr(B) + #10;
  ShowMessage('TBytes array contains:'#10 + S);
end;

See Also