Delphi: How to calculate the SHA hash of a large file

前端 未结 5 668
囚心锁ツ
囚心锁ツ 2021-02-08 05:18

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 ?

相关标签:
5条回答
  • 2021-02-08 05:25

    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;
    
    0 讨论(0)
  • 2021-02-08 05:29

    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.

    0 讨论(0)
  • 2021-02-08 05:39

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

    0 讨论(0)
  • 2021-02-08 05:41

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

    That should provide you with better performances.

    0 讨论(0)
  • 2021-02-08 05:43

    @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.

    0 讨论(0)
提交回复
热议问题