В библиотеке Indy, которая поставляется с Delphi XE2 под 64-битной платформой, имеется баг в вычислении MD4/MD5 (компоненты TIdHashMessageDigest4, TIdHashMessageDigest5 соответственно).
Этот баг был исправлен в более поздних версиях версиях Indy/Delphi (не скажу точно, в какой именно, в Delphi 10.2 Tokyo его нет).
Баг в asm-функциях ROL и ROR в модуле IdGlobalProtocols. Вот как они выглядят в XE2:
Чтобы можно было генерировать MD4/MD5 в XE2 под Win64 без установки новой версии Indy, я сделал модуль IdHashMessageDigestEx с "исправленными" классами TIdHashMessageDigest4Ex и TIdHashMessageDigest5Ex, которыми следует пользоваться вместо TIdHashMessageDigest4 и TIdHashMessageDigest5 соответственно. Замечу, что в XE2 не работает макрос CPU64 (как в более поздних версиях Delphi), а работает CPUX64.
unitIdHashMessageDigestEx;interfaceusesIdFIPS,IdHashMessageDigest;type{$IFDEF VER230}//XE2 TIdHashMessageDigest4Ex=class(TIdHashMessageDigest4)protectedprocedureMDCoder;override;end;TIdHashMessageDigest5Ex=class(TIdHashMessageDigest4Ex)protectedprocedureMDCoder;override;functionInitHash:TIdHashIntCtx;override;publicclassfunctionIsIntfAvailable:Boolean;override;end;{$ELSE}TIdHashMessageDigest4Ex=TIdHashMessageDigest4;TIdHashMessageDigest5Ex=TIdHashMessageDigest5;{$ENDIF}implementation{$IFDEF VER230}//XE2 {$IFDEF NO_NATIVE_ASM)}//XE2 usesIdGlobalProtocols;{$ELSE}// 32-bit: Arg1=EAX, Arg2=DL // 64-bit: Arg1=ECX, Arg2=DL functionROL(constAVal:LongWord;AShift:LongWord):LongWord;assembler;asm{$IFDEF CPUX64} mov eax, ecx {$ENDIF} mov cl, dl rol eax, cl end;{$ENDIF}{ TIdHashMessageDigest4Ex }{$Q-}// Arithmetic operations performed modulo $100000000 procedureTIdHashMessageDigest4Ex.MDCoder;varA,B,C,D,i:LongWord;buff:T16x4LongWordRecord;// 64-byte buffer beginA:=FState[0];B:=FState[1];C:=FState[2];D:=FState[3];fori:=0to15dobeginbuff[i]:=FCBuffer[i*4+0]+(FCBuffer[i*4+1]shl8)+(FCBuffer[i*4+2]shl16)+(FCBuffer[i*4+3]shl24);end;// Round 1 { Note: (x and y) or ( (not x) and z) is equivalent to (((z xor y) and x) xor z) -HHellstrцm }fori:=0to3dobeginA:=ROL((((DxorC)andB)xorD)+A+buff[i*4+0],3);D:=ROL((((CxorB)andA)xorC)+D+buff[i*4+1],7);C:=ROL((((BxorA)andD)xorB)+C+buff[i*4+2],11);B:=ROL((((AxorD)andC)xorA)+B+buff[i*4+3],19);end;// Round 2 { Note: (x and y) or (x and z) or (y and z) is equivalent to ((x and y) or (z and (x or y))) -HHellstrцm }fori:=0to3dobeginA:=ROL(((BandC)or(Dand(BorC)))+A+buff[0*4+i]+$5A827999,3);D:=ROL(((AandB)or(Cand(AorB)))+D+buff[1*4+i]+$5A827999,5);C:=ROL(((DandA)or(Band(DorA)))+C+buff[2*4+i]+$5A827999,9);B:=ROL(((CandD)or(Aand(CorD)))+B+buff[3*4+i]+$5A827999,13);end;// Round 3 A:=ROL((BxorCxorD)+A+buff[0]+$6ED9EBA1,3);D:=ROL((AxorBxorC)+D+buff[8]+$6ED9EBA1,9);C:=ROL((DxorAxorB)+C+buff[4]+$6ED9EBA1,11);B:=ROL((CxorDxorA)+B+buff[12]+$6ED9EBA1,15);A:=ROL((BxorCxorD)+A+buff[2]+$6ED9EBA1,3);D:=ROL((AxorBxorC)+D+buff[10]+$6ED9EBA1,9);C:=ROL((DxorAxorB)+C+buff[6]+$6ED9EBA1,11);B:=ROL((CxorDxorA)+B+buff[14]+$6ED9EBA1,15);A:=ROL((BxorCxorD)+A+buff[1]+$6ED9EBA1,3);D:=ROL((AxorBxorC)+D+buff[9]+$6ED9EBA1,9);C:=ROL((DxorAxorB)+C+buff[5]+$6ED9EBA1,11);B:=ROL((CxorDxorA)+B+buff[13]+$6ED9EBA1,15);A:=ROL((BxorCxorD)+A+buff[3]+$6ED9EBA1,3);D:=ROL((AxorBxorC)+D+buff[11]+$6ED9EBA1,9);C:=ROL((DxorAxorB)+C+buff[7]+$6ED9EBA1,11);B:=ROL((CxorDxorA)+B+buff[15]+$6ED9EBA1,15);Inc(FState[0],A);Inc(FState[1],B);Inc(FState[2],C);Inc(FState[3],D);end;{$Q+}{ TIdHashMessageDigest5Ex }constMD5_SINE:array[1..64]ofLongWord=({ Round 1. }$d76aa478,$e8c7b756,$242070db,$c1bdceee,$f57c0faf,$4787c62a,$a8304613,$fd469501,$698098d8,$8b44f7af,$ffff5bb1,$895cd7be,$6b901122,$fd987193,$a679438e,$49b40821,{ Round 2. }$f61e2562,$c040b340,$265e5a51,$e9b6c7aa,$d62f105d,$02441453,$d8a1e681,$e7d3fbc8,$21e1cde6,$c33707d6,$f4d50d87,$455a14ed,$a9e3e905,$fcefa3f8,$676f02d9,$8d2a4c8a,{ Round 3. }$fffa3942,$8771f681,$6d9d6122,$fde5380c,$a4beea44,$4bdecfa9,$f6bb4b60,$bebfbc70,$289b7ec6,$eaa127fa,$d4ef3085,$04881d05,$d9d4d039,$e6db99e5,$1fa27cf8,$c4ac5665,{ Round 4. }$f4292244,$432aff97,$ab9423a7,$fc93a039,$655b59c3,$8f0ccc92,$ffeff47d,$85845dd1,$6fa87e4f,$fe2ce6e0,$a3014314,$4e0811a1,$f7537e82,$bd3af235,$2ad7d2bb,$eb86d391);{$Q-}// Arithmetic operations performed modulo $100000000 functionTIdHashMessageDigest5Ex.InitHash:TIdHashIntCtx;beginResult:=GetMD5HashInst;end;classfunctionTIdHashMessageDigest5Ex.IsIntfAvailable:Boolean;beginResult:=IsHashingIntfAvailandIsMD5HashIntfAvail;end;procedureTIdHashMessageDigest5Ex.MDCoder;varA,B,C,D:LongWord;i:Integer;x:T16x4LongWordRecord;// 64-byte buffer beginA:=FState[0];B:=FState[1];C:=FState[2];D:=FState[3];fori:=0to15dobeginx[i]:=FCBuffer[i*4+0]+(FCBuffer[i*4+1]shl8)+(FCBuffer[i*4+2]shl16)+(FCBuffer[i*4+3]shl24);end;{ Round 1 }{ Note: (x and y) or ( (not x) and z) is equivalent to (((z xor y) and x) xor z) -HHellstrцm }A:=ROL(A+(((DxorC)andB)xorD)+x[0]+MD5_SINE[1],7)+B;D:=ROL(D+(((CxorB)andA)xorC)+x[1]+MD5_SINE[2],12)+A;C:=ROL(C+(((BxorA)andD)xorB)+x[2]+MD5_SINE[3],17)+D;B:=ROL(B+(((AxorD)andC)xorA)+x[3]+MD5_SINE[4],22)+C;A:=ROL(A+(((DxorC)andB)xorD)+x[4]+MD5_SINE[5],7)+B;D:=ROL(D+(((CxorB)andA)xorC)+x[5]+MD5_SINE[6],12)+A;C:=ROL(C+(((BxorA)andD)xorB)+x[6]+MD5_SINE[7],17)+D;B:=ROL(B+(((AxorD)andC)xorA)+x[7]+MD5_SINE[8],22)+C;A:=ROL(A+(((DxorC)andB)xorD)+x[8]+MD5_SINE[9],7)+B;D:=ROL(D+(((CxorB)andA)xorC)+x[9]+MD5_SINE[10],12)+A;C:=ROL(C+(((BxorA)andD)xorB)+x[10]+MD5_SINE[11],17)+D;B:=ROL(B+(((AxorD)andC)xorA)+x[11]+MD5_SINE[12],22)+C;A:=ROL(A+(((DxorC)andB)xorD)+x[12]+MD5_SINE[13],7)+B;D:=ROL(D+(((CxorB)andA)xorC)+x[13]+MD5_SINE[14],12)+A;C:=ROL(C+(((BxorA)andD)xorB)+x[14]+MD5_SINE[15],17)+D;B:=ROL(B+(((AxorD)andC)xorA)+x[15]+MD5_SINE[16],22)+C;{ Round 2 }{ Note: (x and z) or (y and (not z) ) is equivalent to (((y xor x) and z) xor y) -HHellstrцm }A:=ROL(A+(Cxor(Dand(BxorC)))+x[1]+MD5_SINE[17],5)+B;D:=ROL(D+(Bxor(Cand(AxorB)))+x[6]+MD5_SINE[18],9)+A;C:=ROL(C+(Axor(Band(DxorA)))+x[11]+MD5_SINE[19],14)+D;B:=ROL(B+(Dxor(Aand(CxorD)))+x[0]+MD5_SINE[20],20)+C;A:=ROL(A+(Cxor(Dand(BxorC)))+x[5]+MD5_SINE[21],5)+B;D:=ROL(D+(Bxor(Cand(AxorB)))+x[10]+MD5_SINE[22],9)+A;C:=ROL(C+(Axor(Band(DxorA)))+x[15]+MD5_SINE[23],14)+D;B:=ROL(B+(Dxor(Aand(CxorD)))+x[4]+MD5_SINE[24],20)+C;A:=ROL(A+(Cxor(Dand(BxorC)))+x[9]+MD5_SINE[25],5)+B;D:=ROL(D+(Bxor(Cand(AxorB)))+x[14]+MD5_SINE[26],9)+A;C:=ROL(C+(Axor(Band(DxorA)))+x[3]+MD5_SINE[27],14)+D;B:=ROL(B+(Dxor(Aand(CxorD)))+x[8]+MD5_SINE[28],20)+C;A:=ROL(A+(Cxor(Dand(BxorC)))+x[13]+MD5_SINE[29],5)+B;D:=ROL(D+(Bxor(Cand(AxorB)))+x[2]+MD5_SINE[30],9)+A;C:=ROL(C+(Axor(Band(DxorA)))+x[7]+MD5_SINE[31],14)+D;B:=ROL(B+(Dxor(Aand(CxorD)))+x[12]+MD5_SINE[32],20)+C;{ Round 3. }A:=ROL(A+(BxorCxorD)+x[5]+MD5_SINE[33],4)+B;D:=ROL(D+(AxorBxorC)+x[8]+MD5_SINE[34],11)+A;C:=ROL(C+(DxorAxorB)+x[11]+MD5_SINE[35],16)+D;B:=ROL(B+(CxorDxorA)+x[14]+MD5_SINE[36],23)+C;A:=ROL(A+(BxorCxorD)+x[1]+MD5_SINE[37],4)+B;D:=ROL(D+(AxorBxorC)+x[4]+MD5_SINE[38],11)+A;C:=ROL(C+(DxorAxorB)+x[7]+MD5_SINE[39],16)+D;B:=ROL(B+(CxorDxorA)+x[10]+MD5_SINE[40],23)+C;A:=ROL(A+(BxorCxorD)+x[13]+MD5_SINE[41],4)+B;D:=ROL(D+(AxorBxorC)+x[0]+MD5_SINE[42],11)+A;C:=ROL(C+(DxorAxorB)+x[3]+MD5_SINE[43],16)+D;B:=ROL(B+(CxorDxorA)+x[6]+MD5_SINE[44],23)+C;A:=ROL(A+(BxorCxorD)+x[9]+MD5_SINE[45],4)+B;D:=ROL(D+(AxorBxorC)+x[12]+MD5_SINE[46],11)+A;C:=ROL(C+(DxorAxorB)+x[15]+MD5_SINE[47],16)+D;B:=ROL(B+(CxorDxorA)+x[2]+MD5_SINE[48],23)+C;{ Round 4. }A:=ROL(A+((BornotD)xorC)+x[0]+MD5_SINE[49],6)+B;D:=ROL(D+((AornotC)xorB)+x[7]+MD5_SINE[50],10)+A;C:=ROL(C+((DornotB)xorA)+x[14]+MD5_SINE[51],15)+D;B:=ROL(B+((CornotA)xorD)+x[5]+MD5_SINE[52],21)+C;A:=ROL(A+((BornotD)xorC)+x[12]+MD5_SINE[53],6)+B;D:=ROL(D+((AornotC)xorB)+x[3]+MD5_SINE[54],10)+A;C:=ROL(C+((DornotB)xorA)+x[10]+MD5_SINE[55],15)+D;B:=ROL(B+((CornotA)xorD)+x[1]+MD5_SINE[56],21)+C;A:=ROL(A+((BornotD)xorC)+x[8]+MD5_SINE[57],6)+B;D:=ROL(D+((AornotC)xorB)+x[15]+MD5_SINE[58],10)+A;C:=ROL(C+((DornotB)xorA)+x[6]+MD5_SINE[59],15)+D;B:=ROL(B+((CornotA)xorD)+x[13]+MD5_SINE[60],21)+C;A:=ROL(A+((BornotD)xorC)+x[4]+MD5_SINE[61],6)+B;D:=ROL(D+((AornotC)xorB)+x[11]+MD5_SINE[62],10)+A;C:=ROL(C+((DornotB)xorA)+x[2]+MD5_SINE[63],15)+D;B:=ROL(B+((CornotA)xorD)+x[9]+MD5_SINE[64],21)+C;Inc(FState[0],A);Inc(FState[1],B);Inc(FState[2],C);Inc(FState[3],D);end;{$Q+}{$ENDIF}end.