Крипто-форум crprogram.16mb.com

Програмування, Delphi, криптографія, криптоаналіз, шифри, вихідні коди, вирішення задач, приклади програм

Часовий пояс: UTC десь + 2 години




Розпочати нову тему Відповісти  [ 14 повідомлень ] 
Автор Повідомлення
 Заголовок повідомлення: MD5 / МД5
СообщениеДодано: 09 гру 2014, 20:48 
Не в мережі

Повідомлень: 502
MD5 (Message Digest 5 - Дайджест повідомлення 5) — 128-бітна хеш-функція, яку розробив професор Рональд Л. Рівест в 1991 році, на основі MD4.


Повернутися наверх
  
 
 Заголовок повідомлення: Re: MD5 / МД5
СообщениеДодано: 09 гру 2014, 20:48 
Не в мережі

Повідомлень: 502
md5( "Приклад" ) = af5e757be4d79ff51d30945d58a0e86b


Повернутися наверх
  
 
 Заголовок повідомлення: Re: MD5 / МД5
СообщениеДодано: 09 гру 2014, 20:48 
Не в мережі

Повідомлень: 362
MD5("test") = 098f6bcd4621d373cade4e832627b4f6


Повернутися наверх
  
 
 Заголовок повідомлення: Re: MD5 / МД5
СообщениеДодано: 09 гру 2014, 20:48 
Не в мережі

Повідомлень: 502
В середовищі Lazarus(free Delphi) зберемо проект:
(він нічим не відрізняється від такого ж на делфі):
Код:
function md5s(s:string):string;
var
  a: TMDDigest;
  i: integer;
begin
  Result := '';
  a      := MD5String(s);
  for i := Low(a) to High(a) do
    Result := Result + IntToHex(a[i], 2);
    result:=lowercase(result);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
edit2.Text:=md5s(edit1.text);
end;       


Повернутися наверх
  
 
 Заголовок повідомлення: Re: MD5 / МД5
СообщениеДодано: 09 гру 2014, 20:48 
Не в мережі

Повідомлень: 502
У стандартних модулях Lazarus знайдемо модуль обчислення хеш-функцій МД-2,4,5.
Після деяких змін, які я вніс, а саме викинув з нього все що стосується MD4,MD2 за непотрібністю залишиться чистий MD5:

частина 1:
Код:
{
    This file is part of the Free Pascal packages.
    Copyright (c) 1999-2006 by the Free Pascal development team

    Implements a MD2 digest algorithm (RFC 1319)
    Implements a MD4 digest algorithm (RFC 1320)
    Implements a MD5 digest algorithm (RFC 1321)

    See the file COPYING.FPC, included in this distribution,
    for details about the copyright.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


    changed for http://crprogram.16mb.com
    Tariq
**********************************************************************}

unit md5;

{$mode objfpc}
{$inline on}
{$h+}

interface


(******************************************************************************
* types and constants
******************************************************************************)

const
  MDDefBufSize = 1024;

type
  TMDVersion = (
    MD_VERSION_5
  );

  PMDDigest = ^TMDDigest;
  TMDDigest = array[0..15] of Byte;


  PMD5Digset = PMDDigest;
  TMD5Digest = TMDDigest;

  PMDContext = ^TMDContext;
  TMDHashFunc = procedure(Context: PMDContext; Buffer: Pointer);
  TMDContext = record
    Version : TMDVersion;
    Hash    : TMDHashFunc;
    Align   : PtrUInt;
    State   : array[0..3] of Cardinal;
    BufCnt  : QWord;
    Buffer  : array[0..63] of Byte;
    case Integer of
      0: (Length   : QWord);
      1: (Checksum : array[0..15] of Byte);
  end;


  PMD5Context = PMDContext;
  TMD5Context = TMDContext;



(******************************************************************************
* Core raw functions
******************************************************************************)

procedure MDInit(out Context: TMDContext);
procedure MDUpdate(var Context: TMDContext; var Buf; const BufLen: PtrUInt);
procedure MDFinal(var Context: TMDContext; out Digest: TMDDigest);


(******************************************************************************
* Auxilary functions
******************************************************************************)

function MDString(const S: String; const Version: TMDVersion): TMDDigest;
function MDBuffer(var Buf; const BufLen: PtrUInt; const Version: TMDVersion): TMDDigest;
function MDFile(const Filename: String; const Version: TMDVersion; const Bufsize: PtrUInt = MDDefBufSize): TMDDigest;


(******************************************************************************
* Helper functions
******************************************************************************)

function MDPrint(const Digest: TMDDigest): String;
function MDMatch(const Digest1, Digest2: TMDDigest): Boolean;


(******************************************************************************
* Dedicated raw functions
******************************************************************************)


procedure MD5Init(out Context: TMD5Context); inline;
procedure MD5Update(var Context: TMD5Context; var Buf; const BufLen: PtrUInt); external name 'MD_UPDATE';
procedure MD5Final(var Context: TMD5Context; out Digest: TMD5Digest); external name 'MD_FINAL';


(******************************************************************************
* Dedicated auxilary functions
******************************************************************************)

function MD5String(const S: String): TMD5Digest; inline;
function MD5Buffer(var Buf; const BufLen: PtrUInt): TMD5Digest;
function MD5File(const Filename: String; const Bufsize: PtrUInt = MDDefBufSize): TMD5Digest; inline;



(******************************************************************************
* Dedicated helper functions
******************************************************************************)

function MD5Print(const Digest: TMD5Digest): String; inline;
function MD5Match(const Digest1, Digest2: TMD5Digest): Boolean; inline;

implementation

// inverts the bytes of (Count div 4) cardinals from source to target.
procedure Invert(Source, Dest: Pointer; Count: PtrUInt);
var
  S: PByte;
  T: PCardinal;
  I: PtrUInt;
begin
  S := Source;
  T := Dest;
  for I := 1 to (Count div 4) do
  begin
    T^ := S[0] or (S[1] shl 8) or (S[2] shl 16) or (S[3] shl 24);
    inc(S,4);
    inc(T);
  end;
end;




Повернутися наверх
  
 
 Заголовок повідомлення: Re: MD5 / МД5
СообщениеДодано: 09 гру 2014, 20:48 
Не в мережі

Повідомлень: 502
частина 2:
Код:

procedure MD5Transform(var Context: TMDContext; Buffer: Pointer);

{$push}
{$r-,q-}

  procedure R1(var a: Cardinal; b,c,d,x: Cardinal; s: Byte; ac: Cardinal);
  // F(x,y,z) = (x and y) or ((not x) and z)
  begin
    a := b + roldword(dword(a + {F(b,c,d)}((b and c) or ((not b) and d)) + x + ac), s);
  end;

  procedure R2(var a: Cardinal; b,c,d,x: Cardinal; s: Byte; ac: Cardinal);
  // G(x,y,z) = (x and z) or (y and (not z))
  begin
    a := b + roldword(dword(a + {G(b,c,d)}((b and d) or (c and (not d))) + x + ac), s);
  end;

  procedure R3(var a: Cardinal; b,c,d,x: Cardinal; s: Byte; ac: Cardinal);
  // H(x,y,z) = x xor y xor z;
  begin
    a := b + roldword(dword(a + {H(b,c,d)}(b xor c xor d) + x + ac), s);
  end;

  procedure R4(var a: Cardinal; b,c,d,x: Cardinal; s: Byte; ac: Cardinal);
  // I(x,y,z) = y xor (x or (not z));
  begin
    a := b + roldword(dword(a + {I(b,c,d)}(c xor (b or (not d))) + x + ac), s);
  end;

{$pop}

var
  a, b, c, d: Cardinal;
  Block: array[0..15] of Cardinal;
begin
  Invert(Buffer, @Block, 64);
  a := Context.State[0];
  b := Context.State[1];
  c := Context.State[2];
  d := Context.State[3];

  // Round 1
  R1(a,b,c,d,Block[0] , 7,$d76aa478); R1(d,a,b,c,Block[1] ,12,$e8c7b756); R1(c,d,a,b,Block[2] ,17,$242070db); R1(b,c,d,a,Block[3] ,22,$c1bdceee);
  R1(a,b,c,d,Block[4] , 7,$f57c0faf); R1(d,a,b,c,Block[5] ,12,$4787c62a); R1(c,d,a,b,Block[6] ,17,$a8304613); R1(b,c,d,a,Block[7] ,22,$fd469501);
  R1(a,b,c,d,Block[8] , 7,$698098d8); R1(d,a,b,c,Block[9] ,12,$8b44f7af); R1(c,d,a,b,Block[10],17,$ffff5bb1); R1(b,c,d,a,Block[11],22,$895cd7be);
  R1(a,b,c,d,Block[12], 7,$6b901122); R1(d,a,b,c,Block[13],12,$fd987193); R1(c,d,a,b,Block[14],17,$a679438e); R1(b,c,d,a,Block[15],22,$49b40821);

  // Round 2
  R2(a,b,c,d,Block[1] , 5,$f61e2562); R2(d,a,b,c,Block[6] , 9,$c040b340); R2(c,d,a,b,Block[11],14,$265e5a51); R2(b,c,d,a,Block[0] ,20,$e9b6c7aa);
  R2(a,b,c,d,Block[5] , 5,$d62f105d); R2(d,a,b,c,Block[10], 9,$02441453); R2(c,d,a,b,Block[15],14,$d8a1e681); R2(b,c,d,a,Block[4] ,20,$e7d3fbc8);
  R2(a,b,c,d,Block[9] , 5,$21e1cde6); R2(d,a,b,c,Block[14], 9,$c33707d6); R2(c,d,a,b,Block[3] ,14,$f4d50d87); R2(b,c,d,a,Block[8] ,20,$455a14ed);
  R2(a,b,c,d,Block[13], 5,$a9e3e905); R2(d,a,b,c,Block[2] , 9,$fcefa3f8); R2(c,d,a,b,Block[7] ,14,$676f02d9); R2(b,c,d,a,Block[12],20,$8d2a4c8a);

  // Round 3
  R3(a,b,c,d,Block[5] , 4,$fffa3942); R3(d,a,b,c,Block[8] ,11,$8771f681); R3(c,d,a,b,Block[11],16,$6d9d6122); R3(b,c,d,a,Block[14],23,$fde5380c);
  R3(a,b,c,d,Block[1] , 4,$a4beea44); R3(d,a,b,c,Block[4] ,11,$4bdecfa9); R3(c,d,a,b,Block[7] ,16,$f6bb4b60); R3(b,c,d,a,Block[10],23,$bebfbc70);
  R3(a,b,c,d,Block[13], 4,$289b7ec6); R3(d,a,b,c,Block[0] ,11,$eaa127fa); R3(c,d,a,b,Block[3] ,16,$d4ef3085); R3(b,c,d,a,Block[6] ,23,$04881d05);
  R3(a,b,c,d,Block[9] , 4,$d9d4d039); R3(d,a,b,c,Block[12],11,$e6db99e5); R3(c,d,a,b,Block[15],16,$1fa27cf8); R3(b,c,d,a,Block[2] ,23,$c4ac5665);

  // Round 4
  R4(a,b,c,d,Block[0] , 6,$f4292244); R4(d,a,b,c,Block[7] ,10,$432aff97); R4(c,d,a,b,Block[14],15,$ab9423a7); R4(b,c,d,a,Block[5] ,21,$fc93a039);
  R4(a,b,c,d,Block[12], 6,$655b59c3); R4(d,a,b,c,Block[3] ,10,$8f0ccc92); R4(c,d,a,b,Block[10],15,$ffeff47d); R4(b,c,d,a,Block[1] ,21,$85845dd1);
  R4(a,b,c,d,Block[8] , 6,$6fa87e4f); R4(d,a,b,c,Block[15],10,$fe2ce6e0); R4(c,d,a,b,Block[6] ,15,$a3014314); R4(b,c,d,a,Block[13],21,$4e0811a1);
  R4(a,b,c,d,Block[4] , 6,$f7537e82); R4(d,a,b,c,Block[11],10,$bd3af235); R4(c,d,a,b,Block[2] ,15,$2ad7d2bb); R4(b,c,d,a,Block[9] ,21,$eb86d391);

{$push}
{$r-,q-}
  inc(Context.State[0],a);
  inc(Context.State[1],b);
  inc(Context.State[2],c);
  inc(Context.State[3],d);
{$pop}
  inc(Context.Length,64);
end;


procedure MDInit(out Context: TMDContext);
begin
  FillChar(Context, Sizeof(TMDContext), 0);

        Context.Hash := TMDHashFunc(@MD5Transform);
        Context.Align := 64;
        Context.State[0] := $67452301;
        Context.State[1] := $efcdab89;
        Context.State[2] := $98badcfe;
        Context.State[3] := $10325476;
        Context.Length := 0;
        Context.BufCnt := 0;
end;


procedure MDUpdate(var Context: TMDContext; var Buf; const BufLen: PtrUInt); [public,alias:'MD_UPDATE'];
var
  Align: PtrUInt;
  Src: Pointer;
  Num: PtrUInt;
begin
  if BufLen = 0 then
    Exit;

  Align := Context.Align;
  Src := @Buf;
  Num := 0;

  // 1. Transform existing data in buffer
  if Context.BufCnt > 0 then
  begin
    // 1.1 Try to fill buffer to "Align" bytes
    Num := Align - Context.BufCnt;
    if Num > BufLen then
      Num := BufLen;

    Move(Src^, Context.Buffer[Context.BufCnt], Num);
    Context.BufCnt := Context.BufCnt + Num;
    Src := Pointer(PtrUInt(Src) + Num);

    // 1.2 If buffer contains "Align" bytes, transform it
    if Context.BufCnt = Align then
    begin
      Context.Hash(@Context, @Context.Buffer);
      Context.BufCnt := 0;
    end;
  end;

  // 2. Transform "Align"-Byte blocks of Buf
  Num := BufLen - Num;
  while Num >= Align do
  begin
    Context.Hash(@Context, Src);
    Src := Pointer(PtrUInt(Src) + Align);
    Num := Num - Align;
  end;

  // 3. If there's a block smaller than "Align" Bytes left, add it to buffer
  if Num > 0 then
  begin
    Context.BufCnt := Num;
    Move(Src^, Context.Buffer, Num);
  end;
end;
       


Повернутися наверх
  
 
 Заголовок повідомлення: Re: MD5 / МД5
СообщениеДодано: 09 гру 2014, 20:48 
Не в мережі

Повідомлень: 502
частина 3
Код:

procedure MDFinal(var Context: TMDContext; out Digest: TMDDigest); [public,alias:'MD_FINAL'];
const
{$ifdef FPC_BIG_ENDIAN}
  PADDING_MD45: array[0..15] of Cardinal = ($80000000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
{$else FPC_BIG_ENDIAN}
  PADDING_MD45: array[0..15] of Cardinal = ($80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
{$endif FPC_BIG_ENDIAN}
var
  Length: QWord;
  Pads: Cardinal;
begin
        // 1. Compute length of the whole stream in bits
        Length := 8 * (Context.Length + Context.BufCnt);

        // 2. Append padding bits
        if Context.BufCnt >= 56 then
          Pads := 120 - Context.BufCnt
        else
          Pads := 56 - Context.BufCnt;
        MDUpdate(Context, PADDING_MD45, Pads);

        // 3. Append length of the stream
        Length := NtoLE(Length);
        MDUpdate(Context, Length, 8);

        // 4. Invert state to digest
        Invert(@Context.State, @Digest, 16);

  FillChar(Context, SizeOf(TMDContext), 0);
end;

function MDString(const S: String; const Version: TMDVersion): TMDDigest;
var
  Context: TMDContext;
begin
  MDInit(Context);
  MDUpdate(Context, PChar(S)^, length(S));
  MDFinal(Context, Result);
end;

function MDBuffer(var Buf; const BufLen: PtrUInt; const Version: TMDVersion): TMDDigest;
var
  Context: TMDContext;
begin
  MDInit(Context);
  MDUpdate(Context, buf, buflen);
  MDFinal(Context, Result);
end;

function MDFile(const Filename: String; const Version: TMDVersion; const BufSize: PtrUInt): TMDDigest;
var
  F: File;
  Buf: Pchar;
  Context: TMDContext;
  Count: Cardinal;
  ofm: Longint;
begin
  MDInit(Context);

  Assign(F, Filename);
  {$i-}
  ofm := FileMode;
  FileMode := 0;
  Reset(F, 1);
  {$i+}

  if IOResult = 0 then
  begin
    GetMem(Buf, BufSize);
    repeat
      BlockRead(F, Buf^, Bufsize, Count);
      if Count > 0 then
        MDUpdate(Context, Buf^, Count);
    until Count < BufSize;
    FreeMem(Buf, BufSize);
    Close(F);
  end;

  MDFinal(Context, Result);
  FileMode := ofm;
end;

function MDPrint(const Digest: TMDDigest): String;
var
  I: Byte;
begin
  Result := '';
  for I := 0 to 15 do
    Result := Result + HexStr(Digest[i],2);
  Result := LowerCase(Result);
end;

function MDMatch(const Digest1, Digest2: TMDDigest): Boolean;
var
  A: array[0..3] of Cardinal absolute Digest1;
  B: array[0..3] of Cardinal absolute Digest2;
begin
  Result := (A[0] = B[0]) and (A[1] = B[1]) and (A[2] = B[2]) and (A[3] = B[3]);
end;


procedure MD5Init(out Context: TMD5Context);
begin
  MDInit(Context);
end;


function MD5String(const S: String): TMD5Digest;
begin
  Result := MDString(S, MD_VERSION_5);
end;

function MD5Buffer(var Buf; const BufLen: PtrUInt): TMD5Digest;
begin
  Result := MDBuffer(Buf, BufLen, MD_VERSION_5);
end;

function MD5File(const Filename: String; const Bufsize: PtrUInt): TMD5Digest;
begin
  Result := MDFile(Filename, MD_VERSION_5, Bufsize);
end;

function MD5Print(const Digest: TMD5Digest): String;
begin
  Result := MDPrint(Digest);
end;

function MD5Match(const Digest1, Digest2: TMD5Digest): Boolean;
begin
  Result := MDMatch(Digest1, Digest2);
end;

end.                 


Повернутися наверх
  
 
 Заголовок повідомлення: Re: MD5 / МД5
СообщениеДодано: 09 гру 2014, 20:48 
Не в мережі

Повідомлень: 502
Скачати в архіві:
Приєднання файлів:
md5.rar [3.46 KiB]
Скачали: 193


Повернутися наверх
  
 
 Заголовок повідомлення: Re: MD5 / МД5
СообщениеДодано: 09 гру 2014, 20:48 
Не в мережі

Повідомлень: 502
Для Делфі:

частина 1:
Код:

{ *********************************************************************** }
{                                                                         }
{              MD5 Hashsum Evaluation Unit For Borland Delphi             }
{                                                                         }
{                 Derived from the RSA Data Security, Inc.                }
{                                                                         }
{            MD5 Message-Digest Algorithm described in RFC 1321           }
{                                                                         }
{                     Copyright © 2003, 2009 JetDevels                    }
{                                                                         }
{      ICQ: 509550; e-mail: support@jetdevels.net, jack@uzl.tula.net      }
{ *********************************************************************** }

unit Md5;

interface

uses
  Classes;

type
  //Use for getting result evaluation hashsum
  TMD5Digest = record
    case Boolean of
      False: (A, B, C, D: Integer);
      True: (V: array[0..15] of Byte);
  end;

// Evaluate hashsum
function MD5String(const S: string): TMD5Digest;
function MD5File(const FileName: string): TMD5Digest;
function MD5Stream(const Stream: TStream): TMD5Digest;
function MD5Buffer(const Buffer; Size: Integer): TMD5Digest;
// Converting
function MD5DigestToStr(const Digest: TMD5Digest): string;
function StrToMD5Digest(const Hash: string): TMD5Digest;
// Compare two hashsum
function MD5DigestEquals(const D1, D2: TMD5Digest): Boolean;

implementation

uses
  SysUtils;

type
  PArray4Cardinal = ^TArray4Cardinal;
  TArray4Cardinal = array[0..3] of Cardinal;
  TArray2Cardinal = array[0..1] of Cardinal;
  TArray64Byte = array[0..63] of Byte;

  TMD5Context = record
    State: TArray4Cardinal;
    Count: TArray2Cardinal;
    Buffer: TArray64Byte;
  end;

const
  Padding: TArray64Byte =
    ($80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
       
  S11 = 7;
  S12 = 12;
  S13 = 17;
  S14 = 22;
  S21 = 5;
  S22 = 9;
  S23 = 14;
  S24 = 20;
  S31 = 4;
  S32 = 11;
  S33 = 16;
  S34 = 23;
  S41 = 6;
  S42 = 10;
  S43 = 15;
  S44 = 21;

function RotateLeft(X, N: Cardinal): Cardinal;
begin
  Result := (X shl N) or (X shr (32 - N));
end;

procedure FF(var A: Cardinal; B, C, D, X, S, Ac: Cardinal);
begin
  A := RotateLeft(B and C or not B and D + A + X + Ac, S) + B;
end;

procedure GG(var A: Cardinal; B, C, D, X, S, Ac: Cardinal);
begin
  A := RotateLeft(B and D or C and not D + A + X + Ac, S) + B;
end;

procedure HH(var A: Cardinal; B, C, D, X, S, Ac: Cardinal);
begin
  A := RotateLeft(B xor C xor D + A + X + Ac, S) + B;
end;

procedure II(var A: Cardinal; B, C, D, X, S, Ac: Cardinal);
begin
  A := RotateLeft(B or not D xor C + A + X + Ac, S) + B;
end;


Повернутися наверх
  
 
 Заголовок повідомлення: Re: MD5 / МД5
СообщениеДодано: 09 гру 2014, 20:48 
Не в мережі

Повідомлень: 502
частина 2:
Код:

procedure Transform(State: PArray4Cardinal; Buffer: Pointer);
var
  A, B, C, D: Cardinal;
  X: array[0..15] of Cardinal;
begin
  A := State[0];
  B := State[1];
  C := State[2];
  D := State[3];
  Move(Buffer^, X, 64);
  FF(A, B, C, D, X[0], S11, $D76AA478);
  FF(D, A, B, C, X[1], S12, $E8C7B756);
  FF(C, D, A, B, X[2], S13, $242070DB);
  FF(B, C, D, A, X[3], S14, $C1BDCEEE);
  FF(A, B, C, D, X[4], S11, $F57C0FAF);
  FF(D, A, B, C, X[5], S12, $4787C62A);
  FF(C, D, A, B, X[6], S13, $A8304613);
  FF(B, C, D, A, X[7], S14, $FD469501);
  FF(A, B, C, D, X[8], S11, $698098D8);
  FF(D, A, B, C, X[9], S12, $8B44F7AF);
  FF(C, D, A, B, X[10], S13, $FFFF5BB1);
  FF(B, C, D, A, X[11], S14, $895CD7BE);
  FF(A, B, C, D, X[12], S11, $6B901122);
  FF(D, A, B, C, X[13], S12, $FD987193);
  FF(C, D, A, B, X[14], S13, $A679438E);
  FF(B, C, D, A, X[15], S14, $49B40821);
  GG(A, B, C, D, X[1], S21, $F61E2562);
  GG(D, A, B, C, X[6], S22, $C040B340);
  GG(C, D, A, B, X[11], S23, $265E5A51);
  GG(B, C, D, A, X[0], S24, $E9B6C7AA);
  GG(A, B, C, D, X[5], S21, $D62F105D);
  GG(D, A, B, C, X[10], S22, $2441453);
  GG(C, D, A, B, X[15], S23, $D8A1E681);
  GG(B, C, D, A, X[4], S24, $E7D3FBC8);
  GG(A, B, C, D, X[9], S21, $21E1CDE6);
  GG(D, A, B, C, X[14], S22, $C33707D6);
  GG(C, D, A, B, X[3], S23, $F4D50D87);
  GG(B, C, D, A, X[8], S24, $455A14ED);
  GG(A, B, C, D, X[13], S21, $A9E3E905);
  GG(D, A, B, C, X[2], S22, $FCEFA3F8);
  GG(C, D, A, B, X[7], S23, $676F02D9);
  GG(B, C, D, A, X[12], S24, $8D2A4C8A);
  HH(A, B, C, D, X[5], S31, $FFFA3942);
  HH(D, A, B, C, X[8], S32, $8771F681);
  HH(C, D, A, B, X[11], S33, $6D9D6122);
  HH(B, C, D, A, X[14], S34, $FDE5380C);
  HH(A, B, C, D, X[1], S31, $A4BEEA44);
  HH(D, A, B, C, X[4], S32, $4BDECFA9);
  HH(C, D, A, B, X[7], S33, $F6BB4B60);
  HH(B, C, D, A, X[10], S34, $BEBFBC70);
  HH(A, B, C, D, X[13], S31, $289B7EC6);
  HH(D, A, B, C, X[0], S32, $EAA127FA);
  HH(C, D, A, B, X[3], S33, $D4EF3085);
  HH(B, C, D, A, X[6], S34, $4881D05);
  HH(A, B, C, D, X[9], S31, $D9D4D039);
  HH(D, A, B, C, X[12], S32, $E6DB99E5);
  HH(C, D, A, B, X[15], S33, $1FA27CF8);
  HH(B, C, D, A, X[2], S34, $C4AC5665);
  II(A, B, C, D, X[0], S41, $F4292244);
  II(D, A, B, C, X[7], S42, $432AFF97);
  II(C, D, A, B, X[14], S43, $AB9423A7);
  II(B, C, D, A, X[5], S44, $FC93A039);
  II(A, B, C, D, X[12], S41, $655B59C3);
  II(D, A, B, C, X[3], S42, $8F0CCC92);
  II(C, D, A, B, X[10], S43, $FFEFF47D);
  II(B, C, D, A, X[1], S44, $85845DD1);
  II(A, B, C, D, X[8], S41, $6FA87E4F);
  II(D, A, B, C, X[15], S42, $FE2CE6E0);
  II(C, D, A, B, X[6], S43, $A3014314);
  II(B, C, D, A, X[13], S44, $4E0811A1);
  II(A, B, C, D, X[4], S41, $F7537E82);
  II(D, A, B, C, X[11], S42, $BD3AF235);
  II(C, D, A, B, X[2], S43, $2AD7D2BB);
  II(B, C, D, A, X[9], S44, $EB86D391);
  Inc(State[0], A);
  Inc(State[1], B);
  Inc(State[2], C);
  Inc(State[3], D);
end;

procedure Init(var Context: TMD5Context);
begin
  FillChar(Context, SizeOf(Context), Byte(0));
  Context.State[0] := $67452301;
  Context.State[1] := $EFCDAB89;
  Context.State[2] := $98BADCFE;
  Context.State[3] := $10325476;
end;

procedure Update(var Context: TMD5Context; Input: PByteArray;
  InputLen: Cardinal);
var
  i, Index, PartLen: Cardinal;
begin
  Index := Context.Count[0] shr 3 and $3F;
  Inc(Context.Count[0], InputLen shl 3);
  if Context.Count[0] < InputLen shl 3 then
    Inc(Context.Count[1]);
  Inc(Context.Count[1], InputLen shr 29);
  PartLen := 64 - Index;
  if InputLen >= PartLen then
  begin
    Move(Input^, Context.Buffer[Index], PartLen);
    Transform(@Context.State, @Context.Buffer);
    i := PartLen;
    while i + 63 < InputLen do
    begin
      Transform(@Context.State, @Input[i]);
      Inc(i, 64);
    end;
    Index := 0;
  end
  else
    i := 0;
  Move(Input[i], Context.Buffer[Index], InputLen - i);
end;

procedure Final(var Digest: TMD5Digest; var Context: TMD5Context);
var
  Bits: array[0..7] of Byte;
  Index, PadLen: Cardinal;
begin
  Move(Context.Count, Bits, SizeOf(TArray2Cardinal));
  Index := Context.Count[0] shr 3 and $3F;
  if Index < 56 then
    PadLen := 56 - Index
  else
    PadLen := 120 - Index;
  Update(Context, @Padding, PadLen);
  Update(Context, @Bits, SizeOf(Bits));
  Move(Context.State, Digest, SizeOf(TArray4Cardinal));
end;

function MD5DigestToStr(const Digest: TMD5Digest): string;
var
  i: Integer;
begin
  Result := '';
  for i := 0 to 15 do
    Result := Result + IntToHex(Digest.V[i], 2);
  Result := LowerCase(Result);
end;

function StrToMD5Digest(const Hash: string): TMD5Digest;

  function HexCharToByte(C: Char): Byte;
  begin
    Result := 0;
    case C of
      '0'..'9': Result := Ord(C) - 48;
      'a'..'f': Result := Ord(C) - 87;
    end;
  end;

var
  LCHash: string;
  i: Byte;
begin
  FillChar(Result, 16, Byte(0));
  LCHash := LowerCase(Trim(Hash));
  if Length(LCHash) <> 32 then
    Exit;
  for i := 0 to 15 do
    Result.V[i] := HexCharToByte(LCHash[i * 2 + 1]) shl 4 +
      HexCharToByte(LCHash[i * 2 + 2]);
end;

function MD5String(const S: string): TMD5Digest;
begin
  Result := MD5Buffer(PChar(S)^, Length(S));
end;

function MD5File(const FileName: string): TMD5Digest;
var
  F: TFileStream;
begin
  F := TFileStream.Create(FileName, fmOpenRead);
  try
    Result := MD5Stream(F);
  finally
    F.Free;
  end;
end;


Повернутися наверх
  
 
 Заголовок повідомлення: Re: MD5 / МД5
СообщениеДодано: 09 гру 2014, 20:48 
Не в мережі

Повідомлень: 502
частина 3:

Код:
function MD5Stream(const Stream: TStream): TMD5Digest;
var
  Context: TMD5Context;
  Buffer: array[0..4095] of Byte;
  Size, ReadBytes, TotalBytes, SavePos: Integer;
begin
  Init(Context);
  Size := Stream.Size;
  SavePos := Stream.Position;
  TotalBytes := 0;
  try
    Stream.Seek(0, soFromBeginning);
    repeat
      ReadBytes := Stream.Read(Buffer, SizeOf(Buffer));
      Inc(TotalBytes, ReadBytes);
      Update(Context, @Buffer, ReadBytes);
    until (ReadBytes = 0) or (TotalBytes = Size);
  finally
    Stream.Seek(SavePos, soFromBeginning);
  end;
  Final(Result, Context);
end;

function MD5Buffer(const Buffer; Size: Integer): TMD5Digest;
var
  Context: TMD5Context;
begin
  Init(Context);
  Update(Context, @Buffer, Size);
  Final(Result, Context);
end;

function MD5DigestEquals(const D1, D2: TMD5Digest): Boolean;
begin
  Result := CompareMem(@D1, @D2, SizeOf(TMD5Digest));
end;

end.


Повернутися наверх
  
 
 Заголовок повідомлення: Re: MD5 / МД5
СообщениеДодано: 09 гру 2014, 20:48 
Не в мережі

Повідомлень: 502
Скачати можна в архіві:
Приєднання файлів:
Md5 del.rar [2.61 KiB]
Скачали: 184


Повернутися наверх
  
 
 Заголовок повідомлення: Re: MD5 / МД5
СообщениеДодано: 09 гру 2014, 20:48 
Не в мережі

Повідомлень: 502
Схема одного раунда MD5:
Зображення

Таких раундів 64.

Синій квадрат - додавання по модулю 2^32.

F, G, H, I - функції:
Код:
раунд з 0 по 15
f := (x and y) or ((not x) and x)

раунд з 16 по 31
g := (z and x) or ((not z) and y)

раунд з 32 по 47
h := x xor y xor z

раунд з 48 по 63
i := y xor (x or (not z))


(де x=b,y=c,z=d)

<<<s - циклічний зсув на S біт, де значення зсуву береться з таблиці.
s[0..63] := (7, 12, 17, 22, 7, 12, 17, 22, 7,....

сталі
k[0.. 63] := ( $d76aa478, $e8c7b756, $242070db і т.д.
(з формули 2^32|sin(i)| )

A,B,C,D - початкові сталі:
Цитата:
$67452301;
$efcdab89;
$98badcfe;
$10325476;


M - біти вхідного повідомлення.
Де номер блоку вхідного повідомлення визначається за формулами:

0..15: i
16..31: (5*i + 1) mod 16
32..47: (3*i + 5) mod 16
48..63: (7*i) mod 16


Повернутися наверх
  
 
 Заголовок повідомлення: Re: MD5 / МД5
СообщениеДодано: 09 гру 2014, 20:48 
Не в мережі

Повідомлень: 282
Попри велику кількість нових хеш-алгоритмів, старий добрий MD5 позицій не здає, більше завдяки тому що його код завжди під рукою, і там де супер захист і не потрібен, а це більшість практичних випадків у розробці веб-ресурсів, простих прикладних програм, тощо.


Повернутися наверх
  
 
Показати повідомлення за:  Сортувати по:  
Розпочати нову тему Відповісти  [ 14 повідомлень ] 

Часовий пояс: UTC десь + 2 години



cron
Роwеrеd bу рhрВB® аnd Hostinger web hosting