Delphi: как рассчитать хэш SHA большого файла

Привет, мне нужно сгенерировать SHA для файла размером 5 гигабайт.

Знаете ли вы о библиотеке Delphi, не основанной на строках, которая может это сделать?


person Charles Faiga    schedule 16.02.2009    source источник


Ответы (5)


Вы должны использовать DCPcrypt v2 и читать файл в буфере и передавать хэш SHA буфером пока вы не прочитаете весь файл размером 5 ГБ.

Если вы хотите узнать, как читать большой буферизованный файл, см. мой ответ о копии файла с помощью пользовательской буферизации.

так что в концепции (нет реального кода 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;
person Davy Landman    schedule 16.02.2009
comment
Я не включал реальный код Delphi, потому что в данный момент у меня не установлен компилятор Delphi. - person Davy Landman; 16.02.2009
comment
Я также могу порекомендовать HashLib4Pascal! - person smoothware; 16.03.2019

Я бы порекомендовал 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.

person PetriW    schedule 16.02.2009
comment
да, это тоже хорошо, очень хорошая оптимизация asm :) - person Davy Landman; 16.02.2009

Если я правильно помню, Indy поставляется с несколькими методами хеширования на основе потока.

person dummzeuch    schedule 16.02.2009

Есть интерфейс Delphi для OpenSSL, не так ли?

Это должно обеспечить вам лучшую производительность.

person Edouard A.    schedule 16.02.2009

@ Дэви Лэндман, спасибо, твой ответ мне очень помог. Это код, который я использовал:

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.: Я совсем новичок в Pascal, поэтому этот код, скорее всего, отстой. Но я протестировал его на установщике MSYS2 и смог проверить хэш, так что это хорошо.

person smoothware    schedule 29.12.2018