Delphi:如何计算大文件的 SHA 哈希值

发布于 2024-07-14 05:36:55 字数 69 浏览 6 评论 0原文

您好,我需要在 5 Gig 文件上生成 SHA,

您知道可以执行此操作的非基于字符串的 Delphi 库吗?

Hi I need to generate a SHA over a 5 Gig file

Do you know of a non string based Delphi library that can do this ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

雨落□心尘 2024-07-21 05:36:55

您应该使用 DCPcrypt v2 并读取缓冲的文件并将缓冲区提供给 SHA 哈希器直到您读完完整的 5GB 文件。

如果您想知道如何读取缓冲的大文件,请参阅我的答案关于文件复制使用自定义缓冲

所以在概念上(没有真正的delphi代码!):

function GetShaHash(const AFilename: String)
begin
  sha := TSHAHasher.Create;
  SetLength(Result, sha.Size);
  file := OpenFile(AFilename, GENERIC_READ);
  while not eof file do
  begin
     BytesRead := ReadFile(file, buffer[0], 0, 1024 * 1024);
     sha.Update(buffer[0], BytesRead);
  end;
  sha.Final(Result[0]); 
  CloseFile(file);
end;

You should use DCPcrypt v2 and read your file buffered and feed the SHA hasher with the buffer until you've read the complete 5GB file.

If you want to know how to read a large file buffered, see my answer about a file copy using custom buffering.

so in concept (no real delphi code!):

function GetShaHash(const AFilename: String)
begin
  sha := TSHAHasher.Create;
  SetLength(Result, sha.Size);
  file := OpenFile(AFilename, GENERIC_READ);
  while not eof file do
  begin
     BytesRead := ReadFile(file, buffer[0], 0, 1024 * 1024);
     sha.Update(buffer[0], BytesRead);
  end;
  sha.Final(Result[0]); 
  CloseFile(file);
end;
物价感观 2024-07-21 05:36:55

我推荐 Wolfgang Ehrhardt 的 CRC/Hash。
http://home.netsurf.de/wolfgang.ehrhardt/

速度很快,而且“可以使用最新的 Pascal(TP 5/5.5/6、BP 7、VP 2.1、FPC 1.0/2.0/2.2)和 Delphi 版本(使用 V1 至 V7/9/10 进行测试)进行编译”。

我也用过 D11/D12。

I would recommend Wolfgang Ehrhardt's CRC/Hash.
http://home.netsurf.de/wolfgang.ehrhardt/

It's fast and "can be compiled with most current Pascal (TP 5/5.5/6, BP 7, VP 2.1, FPC 1.0/2.0/2.2) and Delphi versions (tested with V1 up to V7/9/10)".

I've used it with D11/D12 too.

无法言说的痛 2024-07-21 05:36:55

如果我没记错的话,Indy 附带了几种基于流的哈希方法。

If I remember correctly, Indy comes with several a stream based hash methods.

罪#恶を代价 2024-07-21 05:36:55

OpenSSL 有一个 Delphi 接口,不是吗?

这应该会给你带来更好的表现。

There is a Delphi interface for OpenSSL, isn't there?

That should provide you with better performances.

音栖息无 2024-07-21 05:36:55

@戴维·兰德曼,
谢谢你,你的回答对我很有帮助。 这是我最终使用的代码:

function HashFileSHA256(const fileName: String): String;
var
  sha256: TDCP_sha256;
  buffer: array[0..1024*1024] of byte;
  i, bytesRead: Integer;
  streamIn: TFileStream;
  hashBuf: array[0..31] of byte;
begin
  // Initialization
  Result := '';
  streamIn := TFileStream.Create(fileName, fmOpenRead);
  sha256 := TDCP_sha256.Create(nil);
  for i:=0 to Sizeof(buffer) do
    buffer[i] := 0;
  for i:=0 to Sizeof(hashBuf) do
    hashBuf[i] := 0;
  bytesRead := -1;

  // Compute
  try
    sha256.Init;
    while bytesRead <> 0 do
    begin
      bytesRead := streamIn.Read(buffer[0], Sizeof(buffer));
      sha256.Update(buffer[0], bytesRead);
    end;
    sha256.Final(hashBuf);
    for I := 0 to 31 do
      Result := Result + IntToHex(hashBuf[i], 2);
  finally
    streamIn.Free;
    sha256.Free;
  end;

  Result := LowerCase(Result);
end;

PS:我是 Pascal 的初学者,所以这段代码很可能很糟糕。 但我在 MSYS2 安装程序上对其进行了测试,并且能够验证哈希值,所以这很好。

@Davy Landman,
thank you, your answer really helped me out. This is the code I ended up using:

function HashFileSHA256(const fileName: String): String;
var
  sha256: TDCP_sha256;
  buffer: array[0..1024*1024] of byte;
  i, bytesRead: Integer;
  streamIn: TFileStream;
  hashBuf: array[0..31] of byte;
begin
  // Initialization
  Result := '';
  streamIn := TFileStream.Create(fileName, fmOpenRead);
  sha256 := TDCP_sha256.Create(nil);
  for i:=0 to Sizeof(buffer) do
    buffer[i] := 0;
  for i:=0 to Sizeof(hashBuf) do
    hashBuf[i] := 0;
  bytesRead := -1;

  // Compute
  try
    sha256.Init;
    while bytesRead <> 0 do
    begin
      bytesRead := streamIn.Read(buffer[0], Sizeof(buffer));
      sha256.Update(buffer[0], bytesRead);
    end;
    sha256.Final(hashBuf);
    for I := 0 to 31 do
      Result := Result + IntToHex(hashBuf[i], 2);
  finally
    streamIn.Free;
    sha256.Free;
  end;

  Result := LowerCase(Result);
end;

P.S.: I am a total beginner with Pascal, so this code most likely sucks. But I tested it on the MSYS2 installer and was able to verify the hash, so that's nice.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文