delphi - Delphi/Pascal/FreePascal 中的 MD5 用于短字符串

标签 delphi md5 pascal freepascal turbo-pascal

我正在尝试为短字符串(短于 64 字节)实现简单的 MD5。 我正在使用 Wikipedia. 中的算法。 一切都会编译,但我的字符串结果:

"hello world" 

是:

BB3BB65ED0EE1EE0BB22CB93C3CD5A8F

虽然应该是:

5EB63BBBE01EEED093CB22BB8F5ACDC3

完整代码在这里:

program Prog;

uses Classes, SysUtils;

function leftrotate(x, c: Cardinal): Cardinal;
begin
  leftrotate := (x shl c) or (x shr (32-c));
end;

const s: array[0..63] of Cardinal = (
    7, 12, 17, 22,  7, 12, 17, 22,  7, 12, 17, 22,  7, 12, 17, 22,
    5,  9, 14, 20,  5,  9, 14, 20,  5,  9, 14, 20,  5,  9, 14, 20,
    4, 11, 16, 23,  4, 11, 16, 23,  4, 11, 16, 23,  4, 11, 16, 23,
    6, 10, 15, 21,  6, 10, 15, 21,  6, 10, 15, 21,  6, 10, 15, 21 );
K: array[0..63] 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 );

var a0,b0,c0,d0, a,b,c,d, f,g,dTemp: Cardinal;
   Len: Integer;
   Msg: array[0..63] of Char;
   M: array[0..15] of Cardinal absolute Msg; //break chunk into sixteen 32-bit words M[j]
   Str: String;
   i: Integer;
   ff: TFileStream;
   wait: Char;
begin
  a0 := $67452301;
  b0 := $efcdab89;
  c0 := $98badcfe;
  d0 := $10325476;

  Str := 'hello world';
  Len := Length(Str);

  FillChar(Msg, 64, 0);

  for i:=1 to Len do Msg[i-1] := Str[i];

//append "1" bit to message
  Msg[Len] := chr(128);

//append original length in bits mod (2 pow 64) to message
  Msg[63-7] := chr(8*Len);  //Update thanks to @MBo

//Process each 512-bit chunk of message- 1 only have 1 chunk

//TEST dump
//  ff := TFileStream.create('test.txt', fmCreate);
//  ff.write(msg, 64);
//  ff.free;

//Initialize hash value for this chunk:
    A := a0;
    B := b0;
    C := c0;
    D := d0;

//Main loop:
    for i := 0 to 63 do begin

        if (i>=0) and (i<=15) then begin
            F := (B and C) or ((not B) and D);
            g := i;
        end
        else if (i>=16) and (i<=31) then begin
            F := (D and B) or ((not D) and C);
            g := (5*i + 1) mod 16;
        end
        else if (i>=32) and (i<=47) then begin
            F := B xor C xor D;
            g := (3*i + 5) mod 16;
        end
        else if (i>=48) and (i<=63) then begin
            F := C xor (B or (not D));
            g := (7*i) mod 16;
        end;

        dTemp := D;
        D := C;
        C := B;
        B := B + leftrotate((A + F + K[i] + M[g]), s[i]);
        A := dTemp;
    end;

//Add this chunk's hash to result so far:
  a0 := a0 + A;
  b0 := b0 + B;
  c0 := c0 + C;
  d0 := d0 + D;

  //This should give 5EB63BBBE01EEED093CB22BB8F5ACDC3
  Writeln( IntToHex(a0,8) + IntToHex(b0,8) + IntToHex(c0,8)  +IntToHex(d0,8) );

  Readln(wait);
end.

您可以在此处在线尝试代码: http://ideone.com/qdYQ6q

这是我在主循环之前准备好的 block 的转储(test.txt):

enter image description here

最佳答案

最后一步是错误的:

  a0 := a0 + A;
  b0 := b0 + B;
  c0 := c0 + C;
  d0 := d0 + D;

它应该改变字节顺序:

  a0 := Swap32(a0 + A);
  b0 := Swap32(b0 + B);
  c0 := Swap32(c0 + C);
  d0 := Swap32(d0 + D);

function Swap32(ALong: Cardinal): Cardinal; Assembler; 
asm 
  BSWAP eax 
end;

然后就好了。

关于delphi - Delphi/Pascal/FreePascal 中的 MD5 用于短字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27360260/

相关文章:

delphi - 如何使用泛型处理普通动态数组?

oracle - 从数据库读取整数返回 float

android - MD5签名如何影响应用程序安全?

encryption - 从 MD5 哈希函数的特殊应用中恢复电子邮件地址

delphi - 自定义 QuickSort 实现中的 SIGSEGV

string - 删除字符串的特定部分

c# - 相当于什么?在正则表达式中的delphi MatchesMask中?

delphi - 使用 Delphi 的消息关键字处理程序语法与变量常量?

python - 搜索并打印具有相同 MD5 的文件

loops - 在Pascal中“for i:= 0 to i”循环-为什么有效?