* * *

Author Topic: Calculating md5 with with delphi and with freepascal  (Read 3635 times)

Peter Schoenenberg

  • New member
  • *
  • Posts: 14
Calculating md5 with with delphi and with freepascal
« on: May 12, 2017, 05:49:51 am »
I am calculating md5 with embarcadero delphi, getting the right hashs. But when using the same code in lazarus (very basic code, using no libaries), the resulting hashes changes und are wrong (reference is fciv.exe from windows cmd - line). I am knew on lazarus, what could be the error?

Handoko

  • Hero Member
  • *****
  • Posts: 1723
  • My goal: build my own game engine using Lazarus
Re: Calculating md5 with with delphi and with freepascal
« Reply #1 on: May 12, 2017, 05:58:21 am »
Hello Peter Schoenenberg,
Welcome to the forum.

Most Delphi's codes can run on Lazarus but Lazarus is not 100% compatible with Delphi.

You should show us the code, without inspecting the code nothing much we can do.

Thaddy

  • Hero Member
  • *****
  • Posts: 4617
Re: Calculating md5 with with delphi and with freepascal
« Reply #2 on: May 12, 2017, 09:30:42 am »
With plain FPC the hashes are the same as in Delphi.
In Lazarus, when using a byte stream, the results are also the same.
The problem is that in Delphi the default string type is either UTF16 or Ansi. In Lazarus the default string type is UTF8.
That makes the hashes differ.
Same is the case btw with Delphi 7 vs Delphi 2010+

Although using strings is convenient, it is also confusing, for an MD5 hash you should really use a byte stream to obtain the correct digest. Or explicitly use AnsiStrings.
But the hash is always over bytes, so better to get used to bytes instead of strings.
Of course, the digest can then be converted to any string representation for display. But never compare the strings. Compare the digests.
« Last Edit: May 12, 2017, 09:35:59 am by Thaddy »
"Logically, no number of positive outcomes at the level of experimental testing can confirm a scientific theory, but a single counterexample is logically decisive."

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 5804
Re: Calculating md5 with with delphi and with freepascal
« Reply #3 on: May 12, 2017, 11:03:57 am »
Or do what I do, I stuffed the FPC MD5 libs in a DLL, and used them in Delphi :-)

(because they are faster, but anyway...)

Code: Pascal  [Select]
  1. library md5helper;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   Classes,
  7.   md5;
  8.  
  9.  
  10. procedure md5filetoexport(fn:pwidechar;var b: TMD5Digest);
  11. var lfn:unicodestring;
  12. begin
  13.   lfn:=fn;
  14.   b:=MD5File(lfn);
  15. end;
  16.  
  17. exports
  18.   md5filetoexport;
  19. end.
  20.  

Note that the rawbytestring/unicodestring md5 needs FPC trunk, though it will be in 3.0.4 too.

Peter Schoenenberg

  • New member
  • *
  • Posts: 14
Re: Calculating md5 with with delphi and with freepascal
« Reply #4 on: May 12, 2017, 03:42:39 pm »
Thanks for your answers. Beneath I post the code. It is with sha1 and md5. sha1 is ok. It is equal with delphi and with windows fciv.exe, but not md5. I don't see the point. The starting point for md5 - Calculation of md5 of any file is TfrmSha1.cmdLoadFileMD5Click(Sender: TObject). I have to shorten the code because of memory-deficient. Thanks in advanced:

 procedure cmdSha1Click(Sender: TObject);
    procedure cmdLoadFileSha1Click(Sender: TObject);
    procedure cmdMD5Click(Sender: TObject);
    procedure cmdLoadFileMD5Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
    XArr: array of cardinal;
    function UTF8Bytes(const s: UTF8String): TBytes;
    function HashSha1(IntArray: array of Cardinal): String;
    function HashMD5(var IntArray: array of Cardinal): String;
    procedure FieldPreparationsSha1(cAnsiInput: AnsiString);
    procedure FieldPreparationsMD5(cAnsiInput: AnsiString);
    procedure SwapEndiannessOfBits(var Value: cardinal); overload;
    procedure SwapEndiannessOfBits(var Value: uint64); overload;
    function UIntToStr(Value: Cardinal): string; overload;
    function UIntToStr(Value: UInt64): string; overload;
    function F(Xl,Y,Z:Cardinal):Cardinal;
    function G(Xl,Y,Z:Cardinal):Cardinal;
    function H(Xl,Y,Z:Cardinal):Cardinal;
    function J(Xl,Y,Z:Cardinal):Cardinal;
    function SwapLittleBigEndianInteger(Value: Cardinal): Cardinal;
    function SwapLittleBigEndianuInt64(Value: uint64): uint64;

    procedure R1(var A: Cardinal;B,C,D:Cardinal;k,s,i:integer);
    procedure R2(var A: Cardinal;B,C,D:Cardinal;k,s,i:integer);
    procedure R3(var A: Cardinal;B,C,D:Cardinal;k,s,i:integer);
    procedure R4(var A: Cardinal;B,C,D:Cardinal;k,s,i:integer);

  public
    { Public-Deklarationen }
  end;

var
  frmSha1: TfrmSha1;
const
  T:  array[1..64] of Cardinal =
      (
        $d76aa478, $e8c7b756, $242070db, $c1bdceee,
        $f57c0faf, $4787c62a, $a8304613, $fd469501,
        $698098d8, $8b44f7af, $ffff5bb1, $895cd7be,
        $6b901122, $fd987193, $a679438e, $49b40821,
        $f61e2562, $c040b340, $265e5a51, $e9b6c7aa,
        $d62f105d, $02441453, $d8a1e681, $e7d3fbc8,
        $21e1cde6, $c33707d6, $f4d50d87, $455a14ed,
        $a9e3e905, $fcefa3f8, $676f02d9, $8d2a4c8a,
        $fffa3942, $8771f681, $6d9d6122, $fde5380c,
        $a4beea44, $4bdecfa9, $f6bb4b60, $bebfbc70,
        $289b7ec6, $eaa127fa, $d4ef3085, $04881d05,
        $d9d4d039, $e6db99e5, $1fa27cf8, $c4ac5665,
        $f4292244, $432aff97, $ab9423a7, $fc93a039,
        $655b59c3, $8f0ccc92, $ffeff47d, $85845dd1,
        $6fa87e4f, $fe2ce6e0, $a3014314, $4e0811a1,
        $f7537e82, $bd3af235, $2ad7d2bb, $eb86d391
      );

implementation

uses
   math;

{$R *.lfm}

function TfrmSha1.SwapLittleBigEndianuInt64(Value: uint64): uint64;
var Temp, i: Integer;
begin
  Temp := Value;
  Value := 0;
  for i := 0 to 7 do
  begin
    Value := (Value shl 8) or (Temp and $FF);
    Temp := Temp shr 8;
  end;
  Result := Value;
end;
function TfrmSha1.SwapLittleBigEndianInteger(Value: Cardinal): Cardinal;
var Temp, i: Integer;
begin
  Temp := Value;
  Value := 0;
  for i := 0 to 3 do
  begin
    Value := (Value shl 8) or (Temp and $FF);
    Temp := Temp shr 8;
  end;
  Result := Value;
end;

procedure TfrmSha1.R1(var A: Cardinal;B,C,D:Cardinal;k,s,i:integer);
begin
  A := B + (((A + F(B,C,D)+ XArr[k] + T) shl (s)) or ((A + F(B,C,D)+ XArr[k] + T) shr (32-s)));
end;
procedure TfrmSha1.R2(var A: Cardinal;B,C,D:Cardinal;k,s,i:integer);
begin
  A := B + (((A + G(B,C,D)+ XArr[k] + T) shl (s)) or ((A + G(B,C,D)+ XArr[k] + T) shr (32-s)));
end;
procedure TfrmSha1.R3(var A: Cardinal;B,C,D:Cardinal;k,s,i:integer);
begin
  A := B + (((A + H(B,C,D)+ XArr[k] + T) shl (s)) or ((A + H(B,C,D)+ XArr[k] + T) shr (32-s)));
end;
procedure TfrmSha1.R4(var A: Cardinal;B,C,D:Cardinal;k,s,i:integer);
begin
  A := B + (((A + J(B,C,D)+ XArr[k] + T) shl (s)) or ((A + J(B,C,D)+ XArr[k] + T) shr (32-s)));
end;


procedure TfrmSha1.cmdLoadFileMD5Click(Sender: TObject);
var
  by: PByte;
  nLen: integer;
  cAnsiInput: AnsiString;
  cAnsi:AnsiString;
  i: integer;
  tby : TBytes;
  sStream: TMemoryStream;
begin

  edSha1.Text := '';
  memSha.Clear;
  memInput.Clear;

  if not (oOpen.Execute()) then
    exit;
  cAnsiInput := '';
  sStream := TMemoryStream.Create();
  sStream.LoadFromFile(oOpen.FileName);
  nLen := sStream.Size ;
  sStream.Seek(0, soFromBeginning);
  SetLength(tby,nLen);
  sStream.ReadBuffer(tby[0],nLen);
  FreeAndNil(sStream);
  nLen := Length(tby);
 for i := 0 to nLen - 1 do
    begin  // String in AnsiString umwandeln, indem nur das erste Byte vom jeweiligen char
           // genommen wird - bei ASCII kein Problem
      cAnsi := '';
      //by := @cInput;
      by :=  @tby;
      SetString(cAnsi, PAnsiChar(by), 1);
      cAnsiInput := cAnsiInput + cAnsi;
    end;
  //cAnsiInput := UnicodeStringToAnsiString(cInput, 1252);
  if chkAnzeige.Checked then
  begin
    memInput.Clear;
    memInput.Lines.Add(String(cAnsiInput));
  end;
  FieldPreparationsMD5(cAnsiInput);
end;

procedure TfrmSha1.FormCreate(Sender: TObject);
begin

end;


procedure TfrmSha1.FieldPreparationsMD5(cAnsiInput: AnsiString);
var
  AnzahlBytes: Cardinal;
  Anzahl512BitBloecke: Cardinal;
  AnzahlVollstaendigeInteger: Cardinal;
  AnzahlRestInteger:Cardinal;
  AnzahlGesamtInteger: Cardinal;
  IntegerArray: array of Cardinal;
  n, n1, n2: integer;
  hex: string;
  messagelaenge: uint64;
  inthigh, intlow: Cardinal;
  cHash: String;
  i: integer;
begin
  AnzahlBytes := Length(cAnsiInput);
  // 8 Bit pro Byte

  Anzahl512BitBloecke := Floor(((AnzahlBytes  )* 8  + 64 )/ 512) + 1;
  // 16 4Byte - Integer pro 512BitBlock
  AnzahlVollstaendigeInteger := Floor(AnzahlBytes / 4);
  AnzahlRestInteger := AnzahlBytes mod 4;
  AnzahlGesamtInteger := Anzahl512BitBloecke * 16;
  SetLength(IntegerArray, AnzahlGesamtInteger);
  n := AnzahlVollstaendigeInteger - 1;

  for i := 0 to n do
    begin
       n1 := i * 4;
       IntegerArray :=
              16777216 * ord(cAnsiInput[n1+1])+ 65536 * ord(cAnsiInput[n1+2])
                + 256 * ord(cAnsiInput[n1+3]) + ord(cAnsiInput[n1+4]);
    end;
  n1 := AnzahlVollstaendigeInteger * 4;
  //n3 := ord(cAnsiInput[n1+1]);
  case AnzahlRestInteger of
    0: begin
          hex := '80000000';
          IntegerArray[AnzahlVollstaendigeInteger] := StrToInt('$'+hex);
       end;
    1: begin
          hex := '800000';
          IntegerArray[AnzahlVollstaendigeInteger] :=
              16777216 * ord(cAnsiInput[n1+1])+ StrToInt('$'+hex);
       end;
    2: begin
          hex := '8000';
          IntegerArray[AnzahlVollstaendigeInteger] :=
              16777216 * ord(cAnsiInput[n1+1])+ 65536 * ord(cAnsiInput[n1+2])
                + StrToInt('$'+hex);
       end;
    3: begin
          hex := '80';
          IntegerArray[AnzahlVollstaendigeInteger] :=
              16777216 * ord(cAnsiInput[n1+1])+ 65536 * ord(cAnsiInput[n1+2])
                + 256 * ord(cAnsiInput[n1+3]) + StrToInt('$'+hex);
       end;
  end;
  n1 := AnzahlVollstaendigeInteger + 1;
  n2 := AnzahlGesamtInteger - 3;
  for i := n1 to n2 do
    begin
      IntegerArray :=0;
    end;
  messagelaenge := AnzahlBytes * 8;
    // aus Big - Endian einen Little - Endian machen
  messagelaenge := SwapLittleBigEndianuInt64(messagelaenge);

  inthigh := Floor((messagelaenge / 2147483648)/2);
  intlow := messagelaenge - inthigh * 2 * 2147483648;
  IntegerArray[AnzahlGesamtInteger - 2] := inthigh;
  IntegerArray[AnzahlGesamtInteger - 1] := intlow;

  if chkAnzeige.Checked then
  begin
    memSha.Lines.Clear;
    memSha.Lines.Add(String(cAnsiInput));
    n := AnzahlGesamtInteger - 1;
    for i := 0 to n do
      begin
        memSha.Lines.Add(FormatFloat('00',i)+' : ' + IntToStr(IntegerArray));
      end;
        memSha.Lines.Add('#########################');
  end;

  cHash := HashMD5(IntegerArray);

  if chkAnzeige.Checked then
  begin
    //memSha.Lines.Clear;
    memSha.Lines.Add(String(cAnsiInput));
    n := AnzahlGesamtInteger - 1;
    for i := 0 to n do
      begin
        memSha.Lines.Add(FormatFloat('00',i)+' : ' + IntToStr(IntegerArray));
      end;
  end;
  edSha1.Text:= cHash;
end;


function TfrmSha1.HashMD5(var IntArray: array of Cardinal): String;
var
  i, jl, nLen: integer;
  nIntArrayLength, n512BlockAnzahl: integer;
  A , B, C, D, AA, BB, CC, DD: Cardinal;
begin



  // Werte aus IntArray in LittleEndian verwandeln
  //(auch den 64 Bit (messagelaenge) - also noch mal konvertieren?
  nLen := Length(IntArray);
  for i := 0 to (nLen - 1) do
    begin
      IntArray := SwapLittleBigEndianInteger(IntArray);
    end;

  A := $01234567;
  B := $89abcdef;
  C := $fedcba98;
  D := $76543210;

  A := SwapLittleBigEndianInteger(A);
  B := SwapLittleBigEndianInteger(B);
  C := SwapLittleBigEndianInteger(C);
  D := SwapLittleBigEndianInteger(D);


  nIntArrayLength := Length(IntArray);
  n512BlockAnzahl := round(nIntArrayLength / 16);
  SetLength(XArr, 16);
  for i := 0 to (n512BlockAnzahl - 1)  do
    begin
      for jl := 0 to 15 do
      begin
        XArr[jl] := IntArray[16*i+jl];
      end;

      AA := A;
      BB := B;
      CC := C;
      DD := D;

      R1(A,B,C,D,  0, 7,   1);
      R1(D,A,B,C,  1, 12,  2);
      R1(C,D,A,B,  2, 17,  3);
      R1(B,C,D,A,  3, 22,  4);

      R1(A,B,C,D,  4, 7,   5);
      R1(D,A,B,C,  5, 12,  6);
      R1(C,D,A,B,  6, 17,  7);
      R1(B,C,D,A,  7, 22,  8);

      R1(A,B,C,D,  8,  7,  9);
      R1(D,A,B,C,  9, 12, 10);
      R1(C,D,A,B, 10, 17, 11);
      R1(B,C,D,A, 11, 22, 12);

      R1(A,B,C,D, 12,  7, 13);
      R1(D,A,B,C, 13, 12, 14);
      R1(C,D,A,B, 14, 17, 15);
      R1(B,C,D,A, 15, 22, 16);

      R2(A,B,C,D,  1,  5, 17);
      R2(D,A,B,C,  6,  9, 18);
      R2(C,D,A,B, 11, 14, 19);
      R2(B,C,D,A,  0, 20, 20);

      R2(A,B,C,D,  5,  5, 21);
      R2(D,A,B,C, 10,  9, 22);
      R2(C,D,A,B, 15, 14, 23);
      R2(B,C,D,A,  4, 20, 24);

      R2(A,B,C,D,  9,  5, 25);
      R2(D,A,B,C, 14,  9, 26);
      R2(C,D,A,B,  3, 14, 27);
      R2(B,C,D,A,  8, 20, 28);

      R2(A,B,C,D, 13,  5, 29);
      R2(D,A,B,C,  2,  9, 30);
      R2(C,D,A,B,  7, 14, 31);
      R2(B,C,D,A, 12, 20, 32);

      R3(A,B,C,D,  5,  4, 33);
      R3(D,A,B,C,  8, 11, 34);
      R3(C,D,A,B, 11, 16, 35);
      R3(B,C,D,A, 14, 23, 36);

      R3(A,B,C,D,  1,  4, 37);
      R3(D,A,B,C,  4, 11, 38);
      R3(C,D,A,B,  7, 16, 39);
      R3(B,C,D,A, 10, 23, 40);

      R3(A,B,C,D, 13,  4, 41);
      R3(D,A,B,C,  0, 11, 42);
      R3(C,D,A,B,  3, 16, 43);
      R3(B,C,D,A,  6, 23, 44);

      R3(A,B,C,D,  9,  4, 45);
      R3(D,A,B,C, 12, 11, 46);
      R3(C,D,A,B, 15, 16, 47);
      R3(B,C,D,A,  2, 23, 48);

      R4(A,B,C,D,  0,  6, 49);
      R4(D,A,B,C,  7, 10, 50);
      R4(C,D,A,B, 14, 15, 51);
      R4(B,C,D,A,  5, 21, 52);

      R4(A,B,C,D, 12,  6, 53);
      R4(D,A,B,C,  3, 10, 54);
      R4(C,D,A,B, 10, 15, 55);
      R4(B,C,D,A,  1, 21, 56);

      R4(A,B,C,D,  8,  6, 57);
      R4(D,A,B,C, 15, 10, 58);
      R4(C,D,A,B,  6, 15, 59);
      R4(B,C,D,A, 13, 21, 60);

      R4(A,B,C,D,  4,  6, 61);
      R4(D,A,B,C, 11, 10, 62);
      R4(C,D,A,B,  2, 15, 63);
      R4(B,C,D,A,  9, 21, 64);


      A := A + AA;
      B := B + BB;
      C := C + CC;
      D := D + DD;
    end;


  A := SwapLittleBigEndianInteger(A);
  B := SwapLittleBigEndianInteger(B);
  C := SwapLittleBigEndianInteger(C);
  D := SwapLittleBigEndianInteger(D);


  result := IntToHex(A,8)
            + IntToHex(B,8)
            + IntToHex(C,8)
            + IntToHex(D,8);
end;

function TfrmSha1.UIntToStr(Value: Cardinal): string;
begin
  FmtStr(Result, '%u', [Value]);
end;

function TfrmSha1.UIntToStr(Value: UInt64): string;
begin
  FmtStr(Result, '%u', [Value]);
end;


procedure TfrmSha1.SwapEndiannessOfBits(var Value: cardinal);
var
  tmp: cardinal;
  i: Integer;
begin
  tmp := 0;
  for i := 0 to 8*sizeof(Value) - 1 do
    inc(tmp, ((Value shr i) and $1) shl (8*sizeof(Value) - i - 1));
  Value := tmp;
end;

procedure TfrmSha1.SwapEndiannessOfBits(var Value: uint64);
var
  tmp: uint64;
  i: Integer;
begin
  tmp := 0;
  for i := 0 to 8*sizeof(Value) - 1 do
    inc(tmp, ((Value shr i) and $1) shl (8*sizeof(Value) - i - 1));
  Value := tmp;
end;

function TfrmSha1.F(Xl,Y,Z:Cardinal):Cardinal;
begin
   result := ( Xl and Y ) or ( (not Xl) and Z );
end;
function TfrmSha1.G(Xl,Y,Z:Cardinal):Cardinal;
begin
   result := ( Xl and Z ) or ( Y and (not Z));
end;
function TfrmSha1.H(Xl,Y,Z:Cardinal):Cardinal;
begin
   result := Xl Xor Y Xor Z;
end;
function TfrmSha1.J(Xl,Y,Z:Cardinal):Cardinal;
begin
   result := Y Xor (Xl or (not Z));
end;

end.



Thaddy

  • Hero Member
  • *****
  • Posts: 4617
Re: Calculating md5 with with delphi and with freepascal
« Reply #5 on: May 12, 2017, 05:33:34 pm »
You should compare not your own md5 but first the standard md5.pp unit that comes with FPC. It is in packages/hash/source. That is an exact implementation of the exact standard and is verified to be correct.
Try that first. Then we will try to fix YOUR code.

That code is derived from the RSA Data Security, Inc.   MD5 Message-Digest Algorithm described in RFC 1321  http://www.faqs.org/rfcs/rfc1321.html   
Although someone did not give that information in the header. The code is the same as Dinka Maslow wrote in 2002 and which I wrote and translated for KOL in 2003.
Both of these versions have the correct headers (which needs to be corrected) but that does not mean anything for the implementation, because that's the same.
All three are a 1-1 translation of the C sourcecode from RSA that you can find in the link above..

So. First use md5.pp and see what you get: that should be fully conformant. Then report back if you can't find your bug.
« Last Edit: May 12, 2017, 06:07:45 pm by Thaddy »
"Logically, no number of positive outcomes at the level of experimental testing can confirm a scientific theory, but a single counterexample is logically decisive."

Handoko

  • Hero Member
  • *****
  • Posts: 1723
  • My goal: build my own game engine using Lazarus
Re: Calculating md5 with with delphi and with freepascal
« Reply #6 on: May 12, 2017, 06:18:11 pm »
I checked TS's code and found some bugs, eh smilies ...  :D

Weekend is comming,
Let's relax and smile...

Peter Schoenenberg

  • New member
  • *
  • Posts: 14
Re: Calculating md5 with with delphi and with freepascal
« Reply #7 on: May 12, 2017, 06:31:11 pm »
Thanks for your answers and your efforts.
Perhaps the reason lies in the used headers.
Here I use

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics,
  Controls, Forms, Dialogs, StdCtrls;

In Delphi I have used

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

Thanks in advanced

Thaddy

  • Hero Member
  • *****
  • Posts: 4617
Re: Calculating md5 with with delphi and with freepascal
« Reply #8 on: May 12, 2017, 06:40:16 pm »
That should not matter since it is not related to your MD5 code.
"Logically, no number of positive outcomes at the level of experimental testing can confirm a scientific theory, but a single counterexample is logically decisive."

Peter Schoenenberg

  • New member
  • *
  • Posts: 14
Re: Calculating md5 with with delphi and with freepascal
« Reply #9 on: May 12, 2017, 07:10:40 pm »
Could it be, that the sizeof - function in freepascal is different here than in delphi. Remark, the code is ok in delphi. I am working on a 64 bit - computer.
Greetings
Peter

Peter Schoenenberg

  • New member
  • *
  • Posts: 14
Re: Calculating md5 with with delphi and with freepascal
« Reply #10 on: May 12, 2017, 08:20:04 pm »
Here again HashMD5 - Function without Smilys:

function TfrmSha1.HashMD5(var IntArray: array of uint32): String;
var
  i, jl, nLen: integer;
  nIntArrayLength, n512BlockAnzahl: integer;
  A , B, C, D, AA, BB, CC, DD: uint32;
begin



  // Werte aus IntArray in LittleEndian verwandeln
  //(auch den 64 Bit (messagelaenge) - also noch mal konvertieren?
  nLen := Length(IntArray);
  for i := 0 to (nLen - 1) do
    begin
      IntArray := SwapLittleBigEndianInteger(IntArray);
    end;

  A := $01234567;
  B := $89abcdef;
  C := $fedcba98;
  D := $76543210;

  A := SwapLittleBigEndianInteger(A);
  B := SwapLittleBigEndianInteger(B);
  C := SwapLittleBigEndianInteger(C);
  D := SwapLittleBigEndianInteger(D);


  nIntArrayLength := Length(IntArray);
  n512BlockAnzahl := round(nIntArrayLength / 16);
  SetLength(XArr, 16);
  for i := 0 to (n512BlockAnzahl - 1)  do
    begin
      for jl := 0 to 15 do
      begin
        XArr[jl] := IntArray[16*i+jl];
      end;

      AA := A;
      BB := B;
      CC := C;
      DD := D;

      R1(A,B,C,D,  0, 7,   1);
      R1(D,A,B,C,  1, 12,  2);
      R1(C,D,A,B,  2, 17,  3);
      R1(B,C,D,A,  3, 22,  4);

      R1(A,B,C,D,  4, 7,   5);
      R1(D,A,B,C,  5, 12,  6);
      R1(C,D,A,B,  6, 17,  7);
      R1(B,C,D,A,  7, 22,  8);

      R1(A,B,C,D,  8,  7,  9);
      R1(D,A,B,C,  9, 12, 10);
      R1(C,D,A,B, 10, 17, 11);
      R1(B,C,D,A, 11, 22, 12);

      R1(A,B,C,D, 12,  7, 13);
      R1(D,A,B,C, 13, 12, 14);
      R1(C,D,A,B, 14, 17, 15);
      R1(B,C,D,A, 15, 22, 16);

      R2(A,B,C,D,  1,  5, 17);
      R2(D,A,B,C,  6,  9, 18);
      R2(C,D,A,B, 11, 14, 19);
      R2(B,C,D,A,  0, 20, 20);

      R2(A,B,C,D,  5,  5, 21);
      R2(D,A,B,C, 10,  9, 22);
      R2(C,D,A,B, 15, 14, 23);
      R2(B,C,D,A,  4, 20, 24);

      R2(A,B,C,D,  9,  5, 25);
      R2(D,A,B,C, 14,  9, 26);
      R2(C,D,A,B,  3, 14, 27);
      R2(B,C,D,A,  8, 20, 28);

      R2(A,B,C,D, 13,  5, 29);
      R2(D,A,B,C,  2,  9, 30);
      R2(C,D,A,B,  7, 14, 31);
      R2(B,C,D,A, 12, 20, 32);

      R3(A,B,C,D,  5,  4, 33);
      R3(D,A,B,C,  8, 11, 34);
      R3(C,D,A,B, 11, 16, 35);
      R3(B,C,D,A, 14, 23, 36);

      R3(A,B,C,D,  1,  4, 37);
      R3(D,A,B,C,  4, 11, 38);
      R3(C,D,A,B,  7, 16, 39);
      R3(B,C,D,A, 10, 23, 40);

      R3(A,B,C,D, 13,  4, 41);
      R3(D,A,B,C,  0, 11, 42);
      R3(C,D,A,B,  3, 16, 43);
      R3(B,C,D,A,  6, 23, 44);

      R3(A,B,C,D,  9,  4, 45);
      R3(D,A,B,C, 12, 11, 46);
      R3(C,D,A,B, 15, 16, 47);
      R3(B,C,D,A,  2, 23, 48);

      R4(A,B,C,D,  0,  6, 49);
      R4(D,A,B,C,  7, 10, 50);
      R4(C,D,A,B, 14, 15, 51);
      R4(B,C,D,A,  5, 21, 52);

      R4(A,B,C,D, 12,  6, 53);
      R4(D,A,B,C,  3, 10, 54);
      R4(C,D,A,B, 10, 15, 55);
      R4(B,C,D,A,  1, 21, 56);

      R4(A,B,C,D,  8,  6, 57);
      R4(D,A,B,C, 15, 10, 58);
      R4(C,D,A,B,  6, 15, 59);
      R4(B,C,D,A, 13, 21, 60);

      R4(A,B,C,D,  4,  6, 61);
      R4(D,A,B,C, 11, 10, 62);
      R4(C,D,A,B,  2, 15, 63);
      R4(B,C,D,A,  9, 21, 64);


      A := A + AA;
      B := B + BB;
      C := C + CC;
      D := D + DD;
    end;


  A := SwapLittleBigEndianInteger(A);
  B := SwapLittleBigEndianInteger(B);
  C := SwapLittleBigEndianInteger(C);
  D := SwapLittleBigEndianInteger(D);


  result := IntToHex(A,8)
            + IntToHex(B,8)
            + IntToHex(C,8)
            + IntToHex(D,8);
end;
 

and


function TfrmSha1.SwapLittleBigEndianuInt64(Value: uint64): uint64;
var Temp, i: Integer;
begin
  Temp := Value;
  Value := 0;
  for i := 0 to 7 do
  begin
    Value := (Value shl 8) or (Temp and $FF);
    Temp := Temp shr 8;
  end;
  Result := Value;
end;
function TfrmSha1.SwapLittleBigEndianInteger(Value: uint32): uint32;
var Temp, i: Integer;
begin
  Temp := Value;
  Value := 0;
  for i := 0 to 3 do
  begin
    Value := (Value shl 8) or (Temp and $FF);
    Temp := Temp shr 8;
  end;
  Result := Value;
end;

Peter Schoenenberg

  • New member
  • *
  • Posts: 14
Re: Calculating md5 with with delphi and with freepascal
« Reply #11 on: May 12, 2017, 08:22:43 pm »
The Smilys are eights 8

Handoko

  • Hero Member
  • *****
  • Posts: 1723
  • My goal: build my own game engine using Lazarus
Re: Calculating md5 with with delphi and with freepascal
« Reply #12 on: May 12, 2017, 08:43:54 pm »
When posting code in this forum, you can use code tag to make the code more readable and avoid that smiley issue.

jc99

  • Hero Member
  • *****
  • Posts: 516
    • My private Site
Re: Calculating md5 with with delphi and with freepascal
« Reply #13 on: May 12, 2017, 08:52:10 pm »
it's an 8 ) to be exact.

To avoid confusions like these, and you get a better display, is to put code in

[ Code=pascal ]
Your code here ...
[ /Code ] (Without the spaces)
then it looks like
Code: Pascal  [Select]
  1. Function foo:boolean;
  2. begin
  3.   result := true;
  4. end;
  5.  
« Last Edit: May 12, 2017, 08:54:28 pm by jc99 »
OS: Win XP x64, Win 7, Win 7 x64, Win 10, Win 10 x64, Suse Linux 13.2
Laz: 1.2 - 1.6.4, 1.8rc3
https://github.com/joecare99/public
'~|    /''
,_|oe \_,are

Peter Schoenenberg

  • New member
  • *
  • Posts: 14
Re: Calculating md5 with with delphi and with freepascal
« Reply #14 on: May 12, 2017, 09:46:18 pm »
Thanks a lot, I have updated to the newest fpc 3.0.2 and now the I  get the right hashes. The reason could be a compiler bug?
Greetings Peter

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus