文件的MD5校验值

5

这个问题中提到了wcrypt2。

我需要做的就是计算文件的MD5。如果我能在不保存文件的情况下计算它,那就太完美了,因为它是以流格式下载的文件。

我希望有最简单直接的方法来实现这一点。

谢谢!


非常类似于这个:http://stackoverflow.com/questions/1952929/md5-file-hashing-match-delphi-output-with-php-md5file-function - Jeroen Wiert Pluimers
9个回答

16

这是一个可用的 Indy 10 代码示例:

function MD5File(const FileName: string): string;
var
  IdMD5: TIdHashMessageDigest5;
  FS: TFileStream;
begin
 IdMD5 := TIdHashMessageDigest5.Create;
 FS := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
 try
   Result := IdMD5.HashStreamAsHex(FS)
 finally
   FS.Free;
   IdMD5.Free;
 end;
end;

敬礼, OscaR1


+1 对于 fmOpenReadfmShareDenyWrite。太多开发者忘记了这一点。 - Jeroen Wiert Pluimers

5
基于 @dummzeuch 的回答,我编写了以下函数:
function getMD5checksum(s: TStream): string;
 var
  md5: TIdHashMessageDigest5;
  hash : T4x4LongWordRecord;
 begin
  md5 := TIdHashMessageDigest5.Create;
  s.Seek(0,0);
  hash := md5.HashValue(s);
  result := IntToHex(Integer(hash[0]), 4) +
            IntToHex(Integer(hash[1]), 4) +
            IntToHex(Integer(hash[2]), 4) +
            IntToHex(Integer(hash[3]), 4);
 end;

2
要将哈希转换为十六进制字符串,您也可以使用:TIdHashMessageDigest5.AsHex(hash); - The_Fox
IntToHex(Integer(hash[Index]), 4) 会导致字节顺序错误,The_Fox 建议使用的替代方法是正确的。对于更新版本的 Indy,请使用:result := md5.HashStreamAsHex(s); - Sebastian Kirsche
@Sebastian - HashStreamAsHex 返回一个字符串,而且强制转换是不可能的。如何将上面的代码移植到 Indy 10? - ronaldosantana

3

Indy提供了计算多种哈希函数的功能,其中MD5是其中之一。自Delphi 2006以来,Indy已经包含在所有版本的Delphi中,并且可以免费下载用于早期版本。


2

关于什么:

function GetFileMD5(const Stream: TStream): String; overload;
var MD5: TIdHashMessageDigest5;
begin
    MD5 := TIdHashMessageDigest5.Create;
    try
       Result := MD5.HashStreamAsHex(Stream);
    finally
       MD5.Free;
    end;
end;

function GetFileMD5(const Filename: String): String; overload;
var FileStream: TFileStream;
begin
    FileStream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
    try
      Result := GetFileMD5(FileStream);
    finally
      FileStream.Free;
    end;
end;

1
我在 Delphi 7 中使用以下函数和 Indy 10.1.5 相关联。
uses IdHashMessageDigest, idHash, Classes;  

...

function cc_MD5File(const p_fileName : string) : string;
//returns MD5 has for a file
var
  v_idmd5 : TIdHashMessageDigest5;
  v_fs : TFileStream;
  v_hash : T4x4LongWordRecord;
begin
  v_idmd5 := TIdHashMessageDigest5.Create;
  v_fs := TFileStream.Create(p_fileName, fmOpenRead OR fmShareDenyWrite) ;
  try
    v_hash := v_idmd5.HashValue(v_fs);
    result := v_idmd5.AsHex(v_hash);
  finally
    v_fs.Free;
    v_idmd5.Free;
  end;
end;

strtofile('The quick brown fox jumped over the lazy dog''s back', exepath+'foxmd5.txt'); sleep(500)
writeln(cc_MD5File(exepath+'foxmd5.txt'));
E38CA1D920C4B8B8D3946B2C72F01680
- Max Kleiner

1

正如你所提到的,你链接的帖子讨论了wcrypt2,这是一个包含MD5在内的加密例程库。你链接的帖子似乎也表明它可用于Delphi 7,因为提问者包括了标记为“Delphi 7”的输出。你已经给这个问题打上了delphi7的标签,所以我认为那是你正在使用的版本。那么是什么阻止了你使用wcrypt2呢?

这个问题链接到了wcrypt2.pas的副本,在该文件中的版权日期似乎表明该单元已经在Delphi 7发布时可用。检查一下你的安装,也许你已经有了它。如果没有,那么这个单元还说它是通过Project Jedi获得的,所以你可以尝试在那里寻找这个单元。

你引用的问题的答案包括示例Delphi代码和用于执行MD5的Delphi单元名称。它们随着Delphi 2009一起提供,因此您应该检查它们是否对您的版本也可用。


1

看一下 Delphi 中 这个实现 的 MD5SUM。它需要一个字符串作为输入,但我想你可以很容易地让它与流一起工作。


1

Delphi 7有这个吗?我没有那个版本,所以我给出的答案不确定。 - Rob Kennedy
@Rob:MessageDigest_5自Delphi 2005以来就已经可用,但IdHashMessageDigest.pas自Delphi 7起已被包含在内:http://wiert.wordpress.com/2009/12/11/delphi-md5-the-messagedigest_5-unit-has-been-there-since-delphi-2007/ - Jeroen Wiert Pluimers

0

如果你使用Overbyte http://www.overbyte.eu/frame_index.html,只需添加单元并调用名为FileMD5的函数即可获取文件的MD5。

uses OverbyteIcsMd5;
....
function GetMd5File:String; 
begin
 Result := FileMD5(FileName);
end;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接