Delphi: ¿Cómo calcular el hash SHA de un archivo de gran tamaño
Pregunta
Hola necesito para generar un SHA sobre un archivo de Gig 5
¿Conoce un no cordaje de Delphi biblioteca que puede hacer esto?
Solución
Debe utilizar DCPcrypt v2 y leer el archivo de memoria intermedia y alimentar el hasher SHA con el tampón hasta que haya leído el archivo completo 5GB.
Si usted quiere saber cómo leer un archivo de gran tamaño tamponada, véase mi respuesta acerca una copia de archivos utilizando el búfer de encargo .
por lo que en el concepto (sin código de Delphi de verdad!):
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;
Otros consejos
Yo recomendaría de Wolfgang Ehrhardt CRC / Hash.
http://home.netsurf.de/wolfgang.ehrhardt/
Es rápido y "puede ser compilado con más actual Pascal (TP 5 / 5,5 / 6, BP 7, VP 2.1, FPC 1,0 / 2,0 / 2,2) y las versiones de Delphi (probado con V1 hasta V7 / 9/10) ".
Lo he utilizado con D11 / D12 también.
Si no recuerdo mal, Indy viene con varios métodos de hash a partir de un arroyo.
Hay una interfaz de Delphi para OpenSSL, no está allí?
Esto debería proporcionar un mejor rendimiento.
@Davy Landman, Gracias, su respuesta realmente me ayudó. Este es el código que terminé usando:
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 .: Soy un principiante con Pascal, por lo que este código más probable es horrible. Pero he comprobado en el instalador MSYS2 y fue capaz de verificar el hash, por lo que es agradable.