Wenn du den Hash selbst ermitteln musst, dann empfehle ich dir dies Stück für Stück zu tun.
Ich hatte mal Code gepostet, welcher gleich alles las. Das ist natürlich für extrem grosse Files dumm. [Aber für die meisten "normalen Fälle" ausreichend.]
Wenn du über das ganze File hashen willst, dann nimm doch eine vorgefertigte Methode, zum Beispiel
Delphi-Quellcode:
var b : TByte;
rbs : rawbytestring;
...
...
b := System.hash.THashMD5.GetHashBytesFromFile( );
oder
rbs := System.hash.THashMD5.GetHashStringFromFile( );
Schau dir an, wie GetHashBytesFromFile programmiert ist.
...BytesFromFile liefert dir den 128Bit Hash in 16Bytes, und die ...StringFromFile liefert dir einen hex-String der Länge 32.
[Fritz hat mal eine Version gepostet, welche praktisch 1:1 gleich funktioniert. Die Version Fritz hasht aber bei der letzten Tranche über zu viele Bytes und liefert in fast nur in 1/1MB aller Fälle einen korrekten Wert.]
Wenn du nur über Teile eines Files hashen willst, dann könntest du es wie im Code unten tun (ich habe hier die Bytevariante ausgebaut, die hex Variante kannst du daraus ja leicht gewinnen):
Delphi-Quellcode:
procedure AddHashBytes(
var lHasher: THashMD5;
const AStream: TStream; von, bis : int64 );
const
BufferSize = 64*1024;
var
lStreamBytes: TBytes;
Lies, SollLesen : int64;
len : integer;
begin
if bis >= AStream.size
then bis := Astream.size-1;
if von < 0
then von := 0;
if bis >= von
then
begin
setlength(lStreamBytes, BufferSize);
AStream.Position := von;
SollLesen := bis-von+1;
while SollLesen > 0
do
begin
if SollLesen >= BufferSize
then Lies := BufferSize
else Lies := SollLesen;
len := Astream.ReadData(lStreamBytes, Lies);
if len = 0
then break;
dec(SollLesen,len);
lHasher.Update(lStreamBytes, len);
end;
end;
end;
function GetHashFromFile( aFileName :
string; vonbis :
array of int64 ) : TBytes;
var f : TFileStream;
LMD5: THashMD5;
i, len : integer;
von, bis : int64;
begin
f := TFileStream.Create( aFileName, fmOpenRead );
try
LMD5 := THashMD5.Create;
LMD5.Reset;
len := length(vonbis);
if len < 2
then
begin
AddHashBytes( LMD5, f, 0, f.Size-1 );
end
else
begin
i := 0;
while len-i >= 2
do
begin
von := vonbis[i];
bis := vonbis[i+1];
if von < 0
then von := f.Size+von;
if bis < 0
then bis := f.Size+bis;
AddHashBytes( LMD5, f, von, bis);
inc(i,2);
end;
end;
Result := LMD5.HashAsBytes;
finally
f.Free;
end;
end;
Mögliche Aufrufe:
Beispiel 1:
Wenn du von Byte 0 bis 2000 und von Byte 2001 bis ans Ende hashen willst:
GetHashFromFile( filename, [0, 2000, 2001, maxint] );
Damit hashst du ja übers ganze File und erhältst natürlich exakt den gleichen Wert wie via
System.hash.THashMD5.GetHashBytesFromFile( filename );
Beispiel 2:
Wenn du Bytes 192435 - 192450 nicht "mithashen" willst:
GetHashFromFile( filename, [0, 192434, 192451, maxint] );
Beispiel 3:
Negative Werte:
Wenn du die letzten 16 Bytes des Files nicht hashen willst:
GetHashFromFile( filename, [0, -17] );
Ich hoffe, das hilft. Korrekturen bitte direkt an mich - Dankeschön.