home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 October / Chip_2002-10_cd1.bin / zkuste / delphi / kolekce / d56 / FLEXCEL.ZIP / XLSAdapter / UMD5.pas < prev    next >
Pascal/Delphi Source File  |  2002-06-13  |  9KB  |  246 lines

  1. unit uMd5;
  2.  
  3. {$Q-}
  4. {$R-}
  5.  
  6. interface
  7.  
  8. uses
  9.   Windows,
  10.   SysUtils,
  11.   Classes;
  12.  
  13. type
  14.   TMd5Digest = array[0..3] of LongWord;
  15.  
  16.   TMd5Stream = class(TStream)
  17.     private
  18.       BlockCount: Int64;
  19.       BufCount: Cardinal;
  20.       Buffer: array[0..15] of LongWord;
  21.       A: LongWord;
  22.       B: LongWord;
  23.       C: LongWord;
  24.       D: LongWord;
  25.       function F(X, Y, Z: LongWord): LongWord;
  26.       function G(X, Y, Z: LongWord): LongWord;
  27.       function H(X, Y, Z: LongWord): LongWord;
  28.       function I(X, Y, Z: LongWord): LongWord;
  29.       function Rotate(L: LongWord; NumBits: Cardinal): LongWord;
  30.     protected
  31.       procedure AddByte(B: Byte); virtual;
  32.       function GetDigest: TMd5Digest; virtual;
  33.       function GetDigestString: String; virtual;
  34.       procedure Initialize; virtual;
  35.       procedure UpdateDigest; virtual;
  36.     public
  37.       constructor Create;
  38.       function Read(var Buffer; Count: Longint): Longint; override;
  39.       function Seek(Offset: Longint; Origin: Word): Longint; override;
  40.       function Write(const Buffer; Count: Longint): Longint; override;
  41.       property Digest: TMd5Digest read GetDigest;
  42.       property DigestString: String read GetDigestString; end;
  43.  
  44. implementation
  45.  
  46. const
  47.   T: array[1..64] of LongWord = ($D76AA478, $E8C7B756, $242070DB,
  48.     $C1BDCEEE, $F57C0FAF, $4787C62A, $A8304613, $FD469501, $698098D8,
  49.     $8B44F7AF, $FFFF5BB1, $895CD7BE, $6B901122, $FD987193, $A679438E,
  50.     $49B40821, $F61E2562, $C040B340, $265E5A51, $E9B6C7AA, $D62F105D,
  51.     $02441453, $D8A1E681, $E7D3FBC8, $21E1CDE6, $C33707D6, $F4D50D87,
  52.     $455A14ED, $A9E3E905, $FCEFA3F8, $676F02D9, $8D2A4C8A, $FFFA3942,
  53.     $8771F681, $6D9D6122, $FDE5380C, $A4BEEA44, $4BDECFA9, $F6BB4B60,
  54.     $BEBFBC70, $289B7EC6, $EAA127FA, $D4EF3085, $04881D05, $D9D4D039,
  55.     $E6DB99E5, $1FA27CF8, $C4AC5665, $F4292244, $432AFF97, $AB9423A7,
  56.     $FC93A039, $655B59C3, $8F0CCC92, $FFEFF47D, $85845DD1, $6FA87E4F,
  57.     $FE2CE6E0, $A3014314, $4E0811A1, $F7537E82, $BD3AF235, $2AD7D2BB,
  58.     $EB86D391);
  59.  
  60. constructor TMd5Stream.Create;
  61.   begin
  62.   inherited Create;
  63.   Initialize end;
  64.  
  65. procedure TMd5Stream.AddByte(B: Byte);
  66.   begin
  67.   case BufCount mod 4 of
  68.     0:
  69.       Buffer[BufCount div 4] := Buffer[BufCount div 4] or B;
  70.     1:
  71.       Buffer[BufCount div 4] := Buffer[BufCount div 4] or (B shl 8);
  72.     2:
  73.       Buffer[BufCount div 4] := Buffer[BufCount div 4] or (B shl 16);
  74.     3:
  75.       Buffer[BufCount div 4] := Buffer[BufCount div 4] or (B shl 24)
  76.     end;
  77.   Inc(BufCount);
  78.   if BufCount = 64 then
  79.     UpdateDigest end;
  80.  
  81. function TMd5Stream.F(X, Y, Z: LongWord): LongWord;
  82.   begin
  83.   Result := (X and Y) or ((not X) and Z) end;
  84.  
  85. function TMd5Stream.G(X, Y, Z: LongWord): LongWord;
  86.   begin
  87.   Result := (X and Z) or (Y and (not Z)) end;
  88.  
  89. function TMd5Stream.H(X, Y, Z: LongWord): LongWord;
  90.   begin
  91.   Result := X xor Y xor Z end;
  92.  
  93. function TMd5Stream.I(X, Y, Z: LongWord): LongWord;
  94.   begin
  95.   Result := Y xor (X or (not Z)) end;
  96.  
  97. function TMd5Stream.GetDigest: TMd5Digest;
  98.   var
  99.     L: Int64;
  100.     MsgLen: Int64;
  101.   begin
  102.   MsgLen := BlockCount * 512 + BufCount * 8;
  103.   AddByte($80);
  104.   L := 0;
  105.   if BufCount > 56 then
  106.     Write(L, SizeOf(L));
  107.   while BufCount < 56 do
  108.     AddByte(0);
  109.   Write(MsgLen, SizeOf(MsgLen));
  110.   Result[0] := A;
  111.   Result[1] := B;
  112.   Result[2] := C;
  113.   Result[3] := D;
  114.   Initialize end;
  115.  
  116. function TMd5Stream.GetDigestString: String;
  117.   var
  118.     D: TMd5Digest;
  119.   begin
  120.   D := GetDigest;
  121.   SetLength(Result, SizeOf(D));
  122.   Move(D, Result[1], Length(Result)) end;
  123.  
  124. procedure TMd5Stream.Initialize;
  125.   begin
  126.   BlockCount := 0;
  127.   BufCount := 0;
  128.   FillChar(Buffer, SizeOf(Buffer), 0);
  129.   A := $67452301;
  130.   B := $EFCDAB89;
  131.   C := $98BADCFE;
  132.   D := $10325476 end;
  133.  
  134. function TMd5Stream.Read(var Buffer; Count: LongInt): LongInt;
  135.   begin
  136.   Result := 0 end;
  137.  
  138. function TMd5Stream.Rotate(L: LongWord; NumBits: Cardinal): LongWord;
  139.   begin
  140.   Result := (L shl NumBits) + (L shr (32 - NumBits)) end;
  141.  
  142. function TMd5Stream.Seek(Offset: LongInt; Origin: Word): LongInt;
  143.   begin
  144.   Result := BlockCount * 16 + BufCount end;
  145.  
  146. procedure TMd5Stream.UpdateDigest;
  147.   var
  148.     AA: LongWord;
  149.     BB: LongWord;
  150.     CC: LongWord;
  151.     DD: LongWord;
  152.   begin
  153.   Inc(BlockCount);
  154.   AA := A;
  155.   BB := B;
  156.   CC := C;
  157.   DD := D;
  158.  
  159.   A := B + Rotate(A + F(B, C, D) + Buffer[ 0] + T[ 1],  7);
  160.   D := A + Rotate(D + F(A, B, C) + Buffer[ 1] + T[ 2], 12);
  161.   C := D + Rotate(C + F(D, A, B) + Buffer[ 2] + T[ 3], 17);
  162.   B := C + Rotate(B + F(C, D, A) + Buffer[ 3] + T[ 4], 22);
  163.   A := B + Rotate(A + F(B, C, D) + Buffer[ 4] + T[ 5],  7);
  164.   D := A + Rotate(D + F(A, B, C) + Buffer[ 5] + T[ 6], 12);
  165.   C := D + Rotate(C + F(D, A, B) + Buffer[ 6] + T[ 7], 17);
  166.   B := C + Rotate(B + F(C, D, A) + Buffer[ 7] + T[ 8], 22);
  167.   A := B + Rotate(A + F(B, C, D) + Buffer[ 8] + T[ 9],  7);
  168.   D := A + Rotate(D + F(A, B, C) + Buffer[ 9] + T[10], 12);
  169.   C := D + Rotate(C + F(D, A, B) + Buffer[10] + T[11], 17);
  170.   B := C + Rotate(B + F(C, D, A) + Buffer[11] + T[12], 22);
  171.   A := B + Rotate(A + F(B, C, D) + Buffer[12] + T[13],  7);
  172.   D := A + Rotate(D + F(A, B, C) + Buffer[13] + T[14], 12);
  173.   C := D + Rotate(C + F(D, A, B) + Buffer[14] + T[15], 17);
  174.   B := C + Rotate(B + F(C, D, A) + Buffer[15] + T[16], 22);
  175.  
  176.   A := B + Rotate(A + G(B, C, D) + Buffer[ 1] + T[17],  5);
  177.   D := A + Rotate(D + G(A, B, C) + Buffer[ 6] + T[18],  9);
  178.   C := D + Rotate(C + G(D, A, B) + Buffer[11] + T[19], 14);
  179.   B := C + Rotate(B + G(C, D, A) + Buffer[ 0] + T[20], 20);
  180.   A := B + Rotate(A + G(B, C, D) + Buffer[ 5] + T[21],  5);
  181.   D := A + Rotate(D + G(A, B, C) + Buffer[10] + T[22],  9);
  182.   C := D + Rotate(C + G(D, A, B) + Buffer[15] + T[23], 14);
  183.   B := C + Rotate(B + G(C, D, A) + Buffer[ 4] + T[24], 20);
  184.   A := B + Rotate(A + G(B, C, D) + Buffer[ 9] + T[25],  5);
  185.   D := A + Rotate(D + G(A, B, C) + Buffer[14] + T[26],  9);
  186.   C := D + Rotate(C + G(D, A, B) + Buffer[ 3] + T[27], 14);
  187.   B := C + Rotate(B + G(C, D, A) + Buffer[ 8] + T[28], 20);
  188.   A := B + Rotate(A + G(B, C, D) + Buffer[13] + T[29],  5);
  189.   D := A + Rotate(D + G(A, B, C) + Buffer[ 2] + T[30],  9);
  190.   C := D + Rotate(C + G(D, A, B) + Buffer[ 7] + T[31], 14);
  191.   B := C + Rotate(B + G(C, D, A) + Buffer[12] + T[32], 20);
  192.  
  193.   A := B + Rotate(A + H(B, C, D) + Buffer[ 5] + T[33],  4);
  194.   D := A + Rotate(D + H(A, B, C) + Buffer[ 8] + T[34], 11);
  195.   C := D + Rotate(C + H(D, A, B) + Buffer[11] + T[35], 16);
  196.   B := C + Rotate(B + H(C, D, A) + Buffer[14] + T[36], 23);
  197.   A := B + Rotate(A + H(B, C, D) + Buffer[ 1] + T[37],  4);
  198.   D := A + Rotate(D + H(A, B, C) + Buffer[ 4] + T[38], 11);
  199.   C := D + Rotate(C + H(D, A, B) + Buffer[ 7] + T[39], 16);
  200.   B := C + Rotate(B + H(C, D, A) + Buffer[10] + T[40], 23);
  201.   A := B + Rotate(A + H(B, C, D) + Buffer[13] + T[41],  4);
  202.   D := A + Rotate(D + H(A, B, C) + Buffer[ 0] + T[42], 11);
  203.   C := D + Rotate(C + H(D, A, B) + Buffer[ 3] + T[43], 16);
  204.   B := C + Rotate(B + H(C, D, A) + Buffer[ 6] + T[44], 23);
  205.   A := B + Rotate(A + H(B, C, D) + Buffer[ 9] + T[45],  4);
  206.   D := A + Rotate(D + H(A, B, C) + Buffer[12] + T[46], 11);
  207.   C := D + Rotate(C + H(D, A, B) + Buffer[15] + T[47], 16);
  208.   B := C + Rotate(B + H(C, D, A) + Buffer[ 2] + T[48], 23);
  209.  
  210.   A := B + Rotate(A + I(B, C, D) + Buffer[ 0] + T[49],  6);
  211.   D := A + Rotate(D + I(A, B, C) + Buffer[ 7] + T[50], 10);
  212.   C := D + Rotate(C + I(D, A, B) + Buffer[14] + T[51], 15);
  213.   B := C + Rotate(B + I(C, D, A) + Buffer[ 5] + T[52], 21);
  214.   A := B + Rotate(A + I(B, C, D) + Buffer[12] + T[53],  6);
  215.   D := A + Rotate(D + I(A, B, C) + Buffer[ 3] + T[54], 10);
  216.   C := D + Rotate(C + I(D, A, B) + Buffer[10] + T[55], 15);
  217.   B := C + Rotate(B + I(C, D, A) + Buffer[ 1] + T[56], 21);
  218.   A := B + Rotate(A + I(B, C, D) + Buffer[ 8] + T[57],  6);
  219.   D := A + Rotate(D + I(A, B, C) + Buffer[15] + T[58], 10);
  220.   C := D + Rotate(C + I(D, A, B) + Buffer[ 6] + T[59], 15);
  221.   B := C + Rotate(B + I(C, D, A) + Buffer[13] + T[60], 21);
  222.   A := B + Rotate(A + I(B, C, D) + Buffer[ 4] + T[61],  6);
  223.   D := A + Rotate(D + I(A, B, C) + Buffer[11] + T[62], 10);
  224.   C := D + Rotate(C + I(D, A, B) + Buffer[ 2] + T[63], 15);
  225.   B := C + Rotate(B + I(C, D, A) + Buffer[ 9] + T[64], 21);
  226.  
  227.   A := A + AA;
  228.   B := B + BB;
  229.   C := C + CC;
  230.   D := D + DD;
  231.   BufCount := 0;
  232.   FillChar(Buffer, SizeOf(Buffer), 0) end;
  233.  
  234. function TMd5Stream.Write(const Buffer; Count: LongInt): LongInt;
  235. var
  236.   I: Cardinal;
  237.   P: PByteArray;
  238. begin
  239. P := @Buffer;
  240. if Count> 0 then
  241.   for I := 0 to Count - 1 do AddByte(P^[I]);
  242. Result := Count
  243. end;
  244.  
  245. end.
  246.