ActiveDelphi - Índice do Fórum ActiveDelphi
.: O site do programador Delphi! :.
 
 FAQFAQ   PesquisarPesquisar   MembrosMembros   GruposGrupos   RegistrarRegistrar 
 PerfilPerfil   Entrar e ver Mensagens ParticularesEntrar e ver Mensagens Particulares   EntrarEntrar 

[Delphi 2009] Calcular MD5 de um arquivo

 
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Delphi
Exibir mensagem anterior :: Exibir próxima mensagem  
Autor Mensagem
GuhMP
Novato
Novato


Registrado: Sábado, 8 de Agosto de 2009
Mensagens: 39

MensagemEnviada: Dom Ago 16, 2009 8:19 pm    Assunto: [Delphi 2009] Calcular MD5 de um arquivo Responder com Citação

Olá pessoal.

Eu usava o seguinte código no Delphi 7 para calcular o MD5 de um arquivo:

Código:
function MD5(const fileName : string) : string;
var
  idmd5 : TIdHashMessageDigest5;
  fs : TFileStream;
  hash : T4x4LongWordRecord;
begin
  idmd5 := TIdHashMessageDigest5.Create;
  fs := TFileStream.Create(fileName, fmOpenRead OR fmShareDenyWrite) ;
  try
    result := idmd5.AsHex(idmd5.HashValue(fs)) ;
  finally
    fs.Free;
    idmd5.Free;
  end;
end;


Agora eu fui tentar fazer o mesmo no Delphi 2009, mas aconteceu o seguinte erro:

http://img18.imageshack.us/img18/7312/bostaw.jpg

Como arrumar isso? No delphi 7 funcionava perfeitamente Crying or Very sad

Caso alguem tenha algum código que calcule o MD5 de um arquivo, e que seja funcional no Delphi 2009, poste por favor. Razz

Abraço
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
johnny-walker
Moderador
Moderador


Registrado: Sábado, 4 de Outubro de 2003
Mensagens: 10653
Localização: Contagem/MG - BRAZIL

MensagemEnviada: Dom Ago 16, 2009 9:14 pm    Assunto: Responder com Citação

tente esta unit aqui:


[code]

{*_* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

Author: François PIETTE. Based on work given by Louis S. Berman from
BrainTree Ltd, lsb@braintree.com
Description: MD5 is an implementation of the MD5 Message-Digest Algorithm
as described in RFC-1321
Creation: October 11, 1997
Version: 1.05
EMail: francois.piette@overbyte.be http://www.overbyte.be
francois.piette@rtfm.be http://www.rtfm.be/fpiette
francois.piette@pophost.eunet.be
Support: Use the mailing list twsocket@elists.org
Follow "support" link at http://www.overbyte.be for subscription.
Legal issues: Copyright (C) 1997-2005 by François PIETTE
Rue de Grady 24, 4053 Embourg, Belgium. Fax: +32-4-365.74.56
<francois.piette@overbyte.be>

This software is provided 'as-is', without any express or
implied warranty. In no event will the author be held liable
for any damages arising from the use of this software.

Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it
and redistribute it freely, subject to the following
restrictions:

1. The origin of this software must not be misrepresented,
you must not claim that you wrote the original software.
If you use this software in a product, an acknowledgment
in the product documentation would be appreciated but is
not required.

2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.

3. This notice may not be removed or altered from any source
distribution.

4. You must register this software by sending a picture postcard
to the author. Use a nice stamp and mention your name, street
address, EMail address and any comment you like to say.

Updates:
Oct 26, 1997 Changed MD5Final form function to procedure to be compatible
with C++Builder.
Jul 09, 1998 V1.01 Adapted for Delphi 4
Aug 06, 1998 V1.02 Added R- Q- directive
Jun 05, 1999 V1.03 Wolfgang Klein found a bug in MD5Update.
Dec 04, 2002 V1.04 Added function FileMD5 from Leon Zandman <leon@wirwar.com>
Mar 14, 2003 V1.05 Bas Steendijk <steendijk@xs4all.nl> corrected a bug when
file size is exactly 256MB. See comment in code.


* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
unit IcsMD5;

{$I ICSDEFS.INC}

interface

uses
SysUtils, Classes, Forms;

const
MD5Version = 105;
CopyRight : String = ' MD5 Message-Digest (c) 1997-2005 F. Piette V1.05 ';

{$Q-}
{$R-}

type
TMD5Context = record
State: array [0..3] of LongInt;
Count: array [0..1] of LongInt;
case Integer of
0: (BufChar: array [0..63] of Byte);
1: (BufLong: array [0..15] of LongInt);
end;
TMD5Digest = array [0..15] of Char;

procedure MD5Init(var MD5Context: TMD5Context);
procedure MD5Update(var MD5Context: TMD5Context;
const Data;
Len: Integer);
procedure MD5Transform(var Buf: array of LongInt;
const Data: array of LongInt);
procedure MD5UpdateBuffer(var MD5Context: TMD5Context;
Buffer: Pointer;
BufSize: Integer);
procedure MD5Final(var Digest: TMD5Digest; var MD5Context: TMD5Context);

function GetMD5(Buffer: Pointer; BufSize: Integer): string;
function StrMD5(Buffer : String): string;
function FileMD5(const Filename: String) : String;

implementation

const
MaxBufSize = 16384;

type
PMD5Buffer = ^TMD5Buffer;
TMD5Buffer = array [0..(MaxBufSize - 1)] of Char;



{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
{ MD5 initialization. Begins an MD5 operation, writing a new context. }
procedure MD5Init(var MD5Context: TMD5Context);
begin
FillChar(MD5Context, SizeOf(TMD5Context), #0);
with MD5Context do begin
{ Load magic initialization constants. }
State[0] := LongInt($67452301);
State[1] := LongInt($EFCDAB89);
State[2] := LongInt($98BADCFE);
State[3] := LongInt($10325476);
end
end;


{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
{ MD5 block update operation. Continues an MD5 message-digest operation, }
{ processing another message block, and updating the context. }
procedure MD5Update(
var MD5Context: TMD5Context; { Context }
const Data; { Input block }
Len: Integer); { Length of input block }
type
TByteArray = array [0..0] of Byte;
var
Index: Word;
T: LongInt;
begin
with MD5Context do begin
// Acrescentado por min;
Application.ProcessMessages;
T := Count[0];
Inc(Count[0], LongInt(Len) shl 3);
if Cardinal(Count[0]) < Cardinal(T) then {20030314 Bas Steendijk}
Inc(Count[1]);
Inc(Count[1], Len shr 29);
T := (T shr 3) and $3F;
Index := 0;
if T <> 0 then begin
Index := T;
T := 64 - T;
if Len < T then begin
Move(Data, BufChar[Index], Len);
Exit;
end;
Move(Data, BufChar[Index], T);
MD5Transform(State, BufLong);
Dec(Len, T);
Index := T; { Wolfgang Klein, 05/06/99 }
end;
while Len >= 64 do begin
Move(TByteArray(Data)[Index], BufChar, 64);
MD5Transform(State, BufLong);
Inc(Index, 64);
Dec(Len, 64);
end;
Move(TByteArray(Data)[Index], BufChar, Len);
end
end;


{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
{ MD5 finalization. Ends an MD5 message-digest operation, writing the message }
{ digest and zeroizing the context. }
procedure MD5Final(var Digest: TMD5Digest; var MD5Context: TMD5Context);
var
Cnt : Word;
P : Byte;
begin
with MD5Context do begin
Cnt := (Count[0] shr 3) and $3F;
P := Cnt;
BufChar[P] := $80;
Inc(P);
Cnt := 64 - 1 - Cnt;
if Cnt < 8 then begin
FillChar(BufChar[P], Cnt, #0);
MD5Transform(State, BufLong);
FillChar(BufChar, 56, #0);
end
else
FillChar(BufChar[P], Cnt - 8, #0);
BufLong[14] := Count[0];
BufLong[15] := Count[1];
MD5Transform(State, BufLong);
Move(State, Digest, 16)
end;
FillChar(MD5Context, SizeOf(TMD5Context), #0)
end;


{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
{ MD5 basic transformation. Transforms state based on block. }
procedure MD5Transform(
var Buf: array of LongInt;
const Data: array of LongInt);
var
A, B, C, D: LongInt;

procedure Round1(var W: LongInt; X, Y, Z, Data: LongInt; S: Byte);
begin
Inc(W, (Z xor (X and (Y xor Z))) + Data);
W := (W shl S) or (W shr (32 - S));
Inc(W, X)
end;

procedure Round2(var W: LongInt; X, Y, Z, Data: LongInt; S: Byte);
begin
Inc(W, (Y xor (Z and (X xor Y))) + Data);
W := (W shl S) or (W shr (32 - S));
Inc(W, X)
end;

procedure Round3(var W: LongInt; X, Y, Z, Data: LongInt; S: Byte);
begin
Inc(W, (X xor Y xor Z) + Data);
W := (W shl S) or (W shr (32 - S));
Inc(W, X)
end;

procedure Round4(var W: LongInt; X, Y, Z, Data: LongInt; S: Byte);
begin
Inc(W, (Y xor (X or not Z)) + Data);
W := (W shl S) or (W shr (32 - S));
Inc(W, X)
end;
begin
A := Buf[0];
B := Buf[1];
C := Buf[2];
D := Buf[3];

Round1(A, B, C, D, Data[ 0] + LongInt($d76aa478), 7);
Round1(D, A, B, C, Data[ 1] + LongInt($e8c7b756), 12);
Round1(C, D, A, B, Data[ 2] + LongInt($242070db), 17);
Round1(B, C, D, A, Data[ 3] + LongInt($c1bdceee), 22);
Round1(A, B, C, D, Data[ 4] + LongInt($f57c0faf), 7);
Round1(D, A, B, C, Data[ 5] + LongInt($4787c62a), 12);
Round1(C, D, A, B, Data[ 6] + LongInt($a8304613), 17);
Round1(B, C, D, A, Data[ 7] + LongInt($fd469501), 22);
Round1(A, B, C, D, Data[ 8] + LongInt($698098d8), 7);
Round1(D, A, B, C, Data[ 9] + LongInt($8b44f7af), 12);
Round1(C, D, A, B, Data[10] + LongInt($ffff5bb1), 17);
Round1(B, C, D, A, Data[11] + LongInt($895cd7be), 22);
Round1(A, B, C, D, Data[12] + LongInt($6b901122), 7);
Round1(D, A, B, C, Data[13] + LongInt($fd987193), 12);
Round1(C, D, A, B, Data[14] + LongInt($a679438e), 17);
Round1(B, C, D, A, Data[15] + LongInt($49b40821), 22);

Round2(A, B, C, D, Data[ 1] + LongInt($f61e2562), 5);
Round2(D, A, B, C, Data[ 6] + LongInt($c040b340), 9);
Round2(C, D, A, B, Data[11] + LongInt($265e5a51), 14);
Round2(B, C, D, A, Data[ 0] + LongInt($e9b6c7aa), 20);
Round2(A, B, C, D, Data[ 5] + LongInt($d62f105d), 5);
Round2(D, A, B, C, Data[10] + LongInt($02441453), 9);
Round2(C, D, A, B, Data[15] + LongInt($d8a1e681), 14);
Round2(B, C, D, A, Data[ 4] + LongInt($e7d3fbc8), 20);
Round2(A, B, C, D, Data[ 9] + LongInt($21e1cde6), 5);
Round2(D, A, B, C, Data[14] + LongInt($c33707d6), 9);
Round2(C, D, A, B, Data[ 3] + LongInt($f4d50d87), 14);
Round2(B, C, D, A, Data[ 8] + LongInt($455a14ed), 20);
Round2(A, B, C, D, Data[13] + LongInt($a9e3e905), 5);
Round2(D, A, B, C, Data[ 2] + LongInt($fcefa3f8), 9);
Round2(C, D, A, B, Data[ 7] + LongInt($676f02d9), 14);
Round2(B, C, D, A, Data[12] + LongInt($8d2a4c8a), 20);

Round3(A, B, C, D, Data[ 5] + LongInt($fffa3942), 4);
Round3(D, A, B, C, Data[ 8] + LongInt($8771f681), 11);
Round3(C, D, A, B, Data[11] + LongInt($6d9d6122), 16);
Round3(B, C, D, A, Data[14] + LongInt($fde5380c), 23);
Round3(A, B, C, D, Data[ 1] + LongInt($a4beea44), 4);
Round3(D, A, B, C, Data[ 4] + LongInt($4bdecfa9), 11);
Round3(C, D, A, B, Data[ 7] + LongInt($f6bb4b60), 16);
Round3(B, C, D, A, Data[10] + LongInt($bebfbc70), 23);
Round3(A, B, C, D, Data[13] + LongInt($289b7ec6), 4);
Round3(D, A, B, C, Data[ 0] + LongInt($eaa127fa), 11);
Round3(C, D, A, B, Data[ 3] + LongInt($d4ef3085), 16);
Round3(B, C, D, A, Data[ 6] + LongInt($04881d05), 23);
Round3(A, B, C, D, Data[ 9] + LongInt($d9d4d039), 4);
Round3(D, A, B, C, Data[12] + LongInt($e6db99e5), 11);
Round3(C, D, A, B, Data[15] + LongInt($1fa27cf8), 16);
Round3(B, C, D, A, Data[ 2] + LongInt($c4ac5665), 23);

Round4(A, B, C, D, Data[ 0] + LongInt($f4292244), 6);
Round4(D, A, B, C, Data[ 7] + LongInt($432aff97), 10);
Round4(C, D, A, B, Data[14] + LongInt($ab9423a7), 15);
Round4(B, C, D, A, Data[ 5] + LongInt($fc93a039), 21);
Round4(A, B, C, D, Data[12] + LongInt($655b59c3), 6);
Round4(D, A, B, C, Data[ 3] + LongInt($8f0ccc92), 10);
Round4(C, D, A, B, Data[10] + LongInt($ffeff47d), 15);
Round4(B, C, D, A, Data[ 1] + LongInt($85845dd1), 21);
Round4(A, B, C, D, Data[ 8] + LongInt($6fa87e4f), 6);
Round4(D, A, B, C, Data[15] + LongInt($fe2ce6e0), 10);
Round4(C, D, A, B, Data[ 6] + LongInt($a3014314), 15);
Round4(B, C, D, A, Data[13] + LongInt($4e0811a1), 21);
Round4(A, B, C, D, Data[ 4] + LongInt($f7537e82), 6);
Round4(D, A, B, C, Data[11] + LongInt($bd3af235), 10);
Round4(C, D, A, B, Data[ 2] + LongInt($2ad7d2bb), 15);
Round4(B, C, D, A, Data[ 9] + LongInt($eb86d391), 21);

Inc(Buf[0], A);
Inc(Buf[1], B);
Inc(Buf[2], C);
Inc(Buf[3], D);
end;


{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure MD5UpdateBuffer(
var MD5Context: TMD5Context;
Buffer: Pointer;
BufSize: Integer);
var
BufTmp : PMD5Buffer;
BufPtr : PChar;
Bytes : Word;
begin
New(BufTmp);
BufPtr := Buffer;
try
repeat
if BufSize > MaxBufSize then
Bytes := MaxBufSize
else
Bytes := BufSize;
Move(BufPtr^, BufTmp^, Bytes);
Inc(BufPtr, Bytes);
Dec(BufSize, Bytes);
if Bytes > 0 then
MD5Update(MD5Context, BufTmp^, Bytes);
//Acrescentado por min
Application.ProcessMessages;
until Bytes < MaxBufSize;
finally
Dispose(BufTmp);
end;
end;


{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
function GetMD5(Buffer: Pointer; BufSize: Integer): string;
var
I : Integer;
MD5Digest : TMD5Digest;
MD5Context : TMD5Context;
begin
for I := 0 to 15 do
Byte(MD5Digest[I]) := I + 1;
MD5Init(MD5Context);
MD5UpdateBuffer(MD5Context, Buffer, BufSize);
MD5Final(MD5Digest, MD5Context);
Result := '';
for I := 0 to 15 do
begin
Result := Result + IntToHex(Byte(MD5Digest[I]), 2);
// Acrescentado por min
Application.ProcessMessages;
end;
end;


{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
function StrMD5(Buffer : String): string;
begin
Result := GetMD5(@Buffer[1], Length(Buffer));
end;


{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
function FileMD5(const Filename: String) : String;
const
{$IFDEF VER80}
ChunkSize : Cardinal = 1024 * 31;
{$ELSE}
ChunkSize : Cardinal = 102400;
{$ENDIF}
var
I : Integer;
J : Integer;
Num : Integer;
Rest : Integer;
MD5Digest : TMD5Digest;
MD5Context : TMD5Context;
Buf : ^Byte;
Stream : TFileStream;
begin
Result := '';

{ Open file }
Stream := TFileStream.Create(Filename, fmOpenRead or fmShareDenyWrite);
try
{ Allocate buffer to read file }
GetMem(Buf, ChunkSize);
try
{ Initialize MD5 engine }
{ trecho original
for I := 0 to 15 do
Byte(MD5Digest[I]) := I + 1;
}
for I := 0 to 15 do
begin
// Acrescentado por min
Application.ProcessMessages;
Byte(MD5Digest[I]) := I + 1;
end;

MD5Init(MD5Context);

{ Calculate number of full chunks that will fit into the buffer }
Num := Cardinal(Stream.Size) div ChunkSize;
{ Calculate remaining bytes }
Rest := Cardinal(Stream.Size) mod ChunkSize;

{ Set the stream to the beginning of the file }
Stream.Position := 0;

{ Process full chunks }
for J := 0 to Num-1 do begin
Stream.Read(buf^, ChunkSize);
MD5UpdateBuffer(MD5Context, buf, ChunkSize);
end;

{ Process remaining bytes }
if Rest > 0 then begin
Stream.Read(buf^, Rest);
MD5UpdateBuffer(MD5Context, buf, Rest);
end;

finally
FreeMem(Buf, ChunkSize);
end;

{ Finalize MD5 calculation }
MD5Final(MD5Digest, MD5Context);
for I := 0 to 15 do
Result := Result + IntToHex(Byte(MD5Digest[I]), 2);
finally
{ Free the file }
Stream.Free;
end;
end;


{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}


end.

[/code]



bye
_________________
P.O.W.E.R B.Y D.E.L.P.H.I
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular MSN Messenger
gilsonnrodrigues
Moderador
Moderador


Registrado: Quinta-Feira, 14 de Abril de 2005
Mensagens: 9009
Localização: Governador Valadares-MG

MensagemEnviada: Seg Ago 17, 2009 9:33 am    Assunto: Responder com Citação

jonny

esse código tb não funciona no D2009.


veja esse trecho

Código:
Move(State, Digest, 16)



o q ele faz no D7 é o mesmo q faz no D2009, porém embora o State seja a mesma coisa nos dois, não psso dizer o mesmo de Digest


nesse codigo ai ele ta supondo q Digest tem 16 bytes o q é real só no D7.


qdo eu reclamei dessa coisa q fizeram q se justifica ser por causa do unicode, q pra mim foi ... deixa pra lá, mts me disseram q a incompatibilidade é porque eu fazia errado. mas e ai? ai ta errado tb?

e cadê a notificação q disseeam q o d2009 reportaria? (até pq, ele vai reportar o q? ele não sabe o q vc quer)

kd?
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
BugsBunny
Mestre
Mestre


Registrado: Quarta-Feira, 19 de Novembro de 2003
Mensagens: 890

MensagemEnviada: Seg Ago 17, 2009 9:45 am    Assunto: Responder com Citação

Olá velhinho,

Vc tem que baixar a versão do Indy compativel com o delphi 2009.

E o codigo do jonny talvez possa ser adaptado. Mude os parametros "String" por "AnsiString" e veja se funciona.

Bugs
Cool
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
GuhMP
Novato
Novato


Registrado: Sábado, 8 de Agosto de 2009
Mensagens: 39

MensagemEnviada: Seg Ago 17, 2009 10:49 am    Assunto: Responder com Citação

BugsBunny escreveu:
Olá velhinho,

Vc tem que baixar a versão do Indy compativel com o delphi 2009.

E o codigo do jonny talvez possa ser adaptado. Mude os parametros "String" por "AnsiString" e veja se funciona.

Bugs
Cool


Então eu posso usar o código que eu postei sem erros, baixando a versão do Indy para o Delphi 2009? É isso?

O que seria esse indy?

A unica coisa que achei no google, foi Formula Indy KKKK!!!

Abraço.
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
Mostrar os tópicos anteriores:   
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Delphi Todos os horários são GMT - 3 Horas
Página 1 de 1

 
Ir para:  
Enviar Mensagens Novas: Proibido.
Responder Tópicos Proibido
Editar Mensagens: Proibido.
Excluir Mensagens: Proibido.
Votar em Enquetes: Proibido.


Powered by phpBB © 2001, 2005 phpBB Group
Traduzido por: Suporte phpBB