![]() |
MD5-Prüfroutine für Delphi 10.2
Kennt jemand von Euch eine (schnelle) Prüfroutine, die auch Dateien größer als 4GB verarbeitet, unter Delphi 10.2?
Habe bislang eine unit von Matthias Fichtner verwendet, die kann aber nur Dateien < 4GB (nutzt ein FileMapping), eine andere Variante hat zwar bislang unter XE7 funktioniert, geht aber unter Delphi 10.2 nicht. Habe jetzt keine Lust großartige Ursachenforschung zu betreiben, wenn es etwas fertiges (gerne kostenlos) gibt, will ich das Rad hier nicht noch mal neu erfinden. |
AW: MD5-Prüfroutine für Delphi 10.2
Entweder mit den Jedis
Delphi-Quellcode:
Oder mit Wolfgang Ehrhardt Hash-Units
uses
IdHashMessageDigest, IdHash; function MD5File(const FileName: string): string; var IdMD5: TIdHashMessageDigest5; FileStream: TFileStream; begin // if not TFile.Exists(FileName) then // Exit; try IdMD5 := TIdHashMessageDigest5.Create; FileStream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); try Result := Trim(AnsiLowerCase(IdMD5.HashStreamAsHex(FileStream))); finally FileStream.Free; IdMD5.Free; end; except end; end; Nur bei letzterer Möglichkeit weiß ich nicht, wie man die Prüfsumme einer Datei erstellt. |
AW: MD5-Prüfroutine für Delphi 10.2
Zitat:
@Harry: Wenn es schnell sein soll, ist aber CRC32 besser. Was ist der Zweck Deiner Prüfsumme? |
AW: MD5-Prüfroutine für Delphi 10.2
Indy. Meine ich doch. Habe mich geirrt.
Zitat:
Und die sind ja für Schnelligkeit bekannt. Nur bei Verwendung der Units ist darauf zu achten, die Unit Hash umzubenennen. Der Fehler wurde doch angeblich von Embarcadero behoben. Denn wenn man Hash von Wolfgang Erhardt in den uses stehen hat, sucht der Compiler nach System.Hash. |
AW: MD5-Prüfroutine für Delphi 10.2
Danke für die Antworten. Ich benötige die MD5-Funktionalität, um mit meinem Dateimanager z.B. aus dem Netz geladene Dateien zu testen, ob da mit dem Download alles funktioniert hat.
Habe die Indy-Lösung nun mal mit einer 5,3 GB großen Datei getestet (liegt auf einer Festplatte, die per 1GB-Netz verbunden ist), da hat es 4 Minuten gedauert, bis das (richtige) Ergebnis kam. |
AW: MD5-Prüfroutine für Delphi 10.2
Zitat:
CRC32 ist für dein Vorhaben eher ungeeignet soweit ich weiß. ![]() |
AW: MD5-Prüfroutine für Delphi 10.2
Habe mal schnell ein Linux-Testprogramm gemacht (da mein Windows virtuell in Virtual-Box verwendet wird), da dauert das (immer noch Festplatte, aber kein Netz) ca. 1:10 Minuten. Damit kann ich leben... (alleine das Kopieren bzw. Lesen einer Datei in dieser Größe dauert mind. 30 Sekunden, da ist das denke ich schon recht schnell).
Also danke für den schnellen Tip! |
AW: MD5-Prüfroutine für Delphi 10.2
Du wärst noch schneller dran, wenn du Wolfgang Erhardts Units verwenden und einen Stream hashen würdest.
Hier für einen String. für einen Stream weiß ich nicht wie es funktioniert
Delphi-Quellcode:
function MD5(const s: UTF8String): string;
var Context: THashContext; Hash: TMD5Digest; begin MD5Init(Context); MD5Update(Context, PAnsiChar(s), Length(s) * SizeOf(Byte)); MD5Final(Context, Hash); Result := string(Mem_Util.HexStr(@Hash, SizeOf(Hash))); end; |
AW: MD5-Prüfroutine für Delphi 10.2
es gibt noch die DCP Sachen, die haben auch MD5 mit drin, sind open source und nicht so vollgeladen wie die Indy Komponenten.
Da geht es dann so :
Code:
uses DCPmd5;
function FileMD5(const AFileName: string): String; var DCP_md51: TDCP_md5; aStream: TFileStream; Buffer: array[0..16383] of Byte; Read, i : Integer; HashDigest: array of byte; begin DCP_md51 := TDCP_md5.Create(nil); DCP_md51.Init; aStream := TFileStream.Create(AFileName, fmOpenRead); Repeat Read := aStream.Read(Buffer, Sizeof(Buffer)); DCP_md51.Update(Buffer, Read) Until Read <> Sizeof(Buffer); aStream.Free; SetLength(HashDigest, DCP_md51.HashSize div 8); DCP_md51.Final(HashDigest[0]); // Read the MD5 Result := EmptyStr; for i := 0 to Length(HashDigest) - 1 Do // end convert into hex Result := Result + IntToHex(HashDigest[i], 2); DCP_md51.Free; end; |
AW: MD5-Prüfroutine für Delphi 10.2
Um das zu kompletieren. Gibt es jemanden der eine funktionierende Implementierung (Datei / Stream hashen) mit den WE-Units fertig bekommt?
|
AW: MD5-Prüfroutine für Delphi 10.2
Zitat:
![]()
Delphi-Quellcode:
Also für MD5 die
procedure [Hash]File(fname: Str255; var Digest: T[Hash]Digest; var buf; bsize: word; var Err: word);
{-[Hash] of file, buf: buffer with at least bsize bytes}
Delphi-Quellcode:
. Allerdings ist in Unit Hash wg. 16-Bit-Kompatibilität nur ein max. 64-KB-Buffer implementiert:
procedure MD5File
Delphi-Quellcode:
procedure HashFile(const fname: Str255; PHash: PHashDesc;
var Digest: THashDigest; var buf; bsize: word; var Err: word); {-Calculate hash digest of file, buf: buffer with at least bsize bytes} |
AW: MD5-Prüfroutine für Delphi 10.2
Zitat:
Code:
function MD5(const AFileName: String): string;
var Context: THashContext; Hash: TMD5Digest; aStream : TMemoryStream; begin aStream := TTMemoryStream.Create; aStream.LoadFromFile(AFileName); MD5Init(Context); MD5Update(Context, aStream.Memory^, aStream.Size); MD5Final(Context, Hash); Result := string(Mem_Util.HexStr(@Hash, SizeOf(Hash))); aStream.Free; end; |
AW: MD5-Prüfroutine für Delphi 10.2
Zitat:
Delphi-Quellcode:
Und das Ergebnis für ein File mit 512 MB nur 'a':
program md5file;
{$apptype console} uses system.classes, hash, md5, mem_util; function MD5F(const AFileName: String): string; var Context: THashContext; Hash: TMD5Digest; aStream : TMemoryStream; begin aStream := TMemoryStream.Create; aStream.LoadFromFile(AFileName); MD5Init(Context); MD5UpdateXL(Context, aStream.Memory, aStream.Size); MD5Final(Context, Hash); Result := string(Mem_Util.HexStr(@Hash, SizeOf(Hash))); aStream.Free; end; begin writeln(MD5F(paramstr(1))); end.
Code:
D:\Work\CRC_HASH>timethis md5file 512MB_A
TimeThis : Command Line : md5file 512MB_A TimeThis : Start Time : Sun Nov 26 20:32:01 2017 31e4d9c6d74cd592b78f77f72965d6ab TimeThis : Command Line : md5file 512MB_A TimeThis : Start Time : Sun Nov 26 20:32:01 2017 TimeThis : End Time : Sun Nov 26 20:32:04 2017 TimeThis : Elapsed Time : 00:00:02.840 |
AW: MD5-Prüfroutine für Delphi 10.2
Zitat:
Zitat:
|
AW: MD5-Prüfroutine für Delphi 10.2
Eine beliebige Datei (hier 5,3GB) komplett in MemoryStream einlesen ist doch Wahnsinn... morgen ist es eine 15GB Datei und da is auch in 64bit mit 16GB Ram schluss mit lustig...
- weil es sich schön rechnen lässt und "etwas" RAM heutzutage ja da ist, würde ich 2 Threads und 2x100MB Puffer nutzen... - ein Thread liest je 100MB Puffer ein, das sollte bei heutigen HDD 0,5..1sec(=100..200MB/sec) dauern und ist per SSD noch schneller - ein Thread rechnet den MD5 über den jeweils geladenen 100MB Puffer - plus irgendwas einfaches als "Sync" => ich denke das wird die schnellste und noch einfach zu programmierende Variante ergeben, weil NextLoad&Calc auf heutigen mindestens DualCores echt parallel ablaufen -> nebenbei trennt man so sauber Load&Calc, sodass man simpel diee jeweiligen Ausführungszeiten getrennt aufsummieren kann |
AW: MD5-Prüfroutine für Delphi 10.2
Zitat:
Der kann jedenfalls beliebig große Dateien, da er immer in Blöcken von 4096 Bytes in einer Schleife ausliest und den MD5 updated, bis zum Dateiende.
Delphi-Quellcode:
program Project3;
{$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, System.Hash; procedure Main; var MyFilename: string; begin MyFilename := 'C:\Users\Public\Documents\Embarcadero\Studio\17.0\PlatformSDKs\android-sdk-windows\system-images\android-23\android-tv\armeabi-v7a\system.img'; Writeln(THashMD5.GetHashStringFromFile(MyFilename)); end; begin try Main; Readln; except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end. |
AW: MD5-Prüfroutine für Delphi 10.2
Zitat:
Code:
D:\Work\CRC_HASH>timethis md5fileb.exe 512MB_A
TimeThis : Command Line : md5fileb.exe 512MB_A TimeThis : Start Time : Mon Nov 27 09:33:02 2017 sizeof(buf)= 61440 31e4d9c6d74cd592b78f77f72965d6ab TimeThis : Command Line : md5fileb.exe 512MB_A TimeThis : Start Time : Mon Nov 27 09:33:02 2017 TimeThis : End Time : Mon Nov 27 09:33:05 2017 TimeThis : Elapsed Time : 00:00:02.474 |
AW: MD5-Prüfroutine für Delphi 10.2
Nur als Anmerkung nebenbei:
Überleg dir vllt. ob du einen anderen Hash benutzt als MD5. MD5 ist veraltet und geknackt. |
AW: MD5-Prüfroutine für Delphi 10.2
Zitat:
Es geht hier nicht um Passwörter oder sowas! Die Anbieter von großen Downloads bieten neben dem Download-Link auch den von ihnen berechneten Hash-Wert (siehe Emba-Link unten). Nach dem Runterladen der Datei kann man über die runtergeladene Datei selber den Hash ziehen und mit dem originalen Hash vergleichen. Wenn alles gut ist, dann ist die Datei korrekt runtergeladen. Beispiel: ![]() |
AW: MD5-Prüfroutine für Delphi 10.2
Zitat:
Aber auch bei Dateien lässt sich das ganze ausnutzen und der Benutzer bekommt eine Datei mit gleichem Hash aber anderem (bösartigem) Inhalt. Ich will ja jetzt nicht zwangsweise den Teufel an die Wand malen. Ich will nur sagen, dass man nichts zu verlieren und nur gewinnen kann wenn man sich für ein sichereres Hashverfahren entscheidet. Und bei den meisten Hash-Bibliotheken reicht es die Deklaration seines Hash-Objekts von TMD5Hash (o.ä.) auf TSHA3Hash (o.ä.) umzuändern und man ist auf der sicheren Seite. |
AW: MD5-Prüfroutine für Delphi 10.2
Zitat:
|
AW: MD5-Prüfroutine für Delphi 10.2
Ja okay. Wenn man nicht selbst die Downloads anbietet und der Anbieter nur einen MD5 Hash liefert dann nehme ich alles zurück.
Dann bringts einem natürlich nichts irgendeinen anderen Hash auszurechnen. |
AW: MD5-Prüfroutine für Delphi 10.2
Mich haben, wenn ich ihn so nennen darf, Wolfgang's Units noch nie enttäuscht.
Sie arbeiten schnell, zuverlässig und bringen keinen unnötigen Müll mit. |
AW: MD5-Prüfroutine für Delphi 10.2
Zitat:
|
AW: MD5-Prüfroutine für Delphi 10.2
Zitat:
Delphi-Quellcode:
Und als Kommentar in Hash.HashFile: {-Calculate hash digest of file, buf: buffer with at least bsize bytes}
procedure MD5File(const fname: Str255; var Digest: TMD5Digest; var buf; bsize: word; var Err: word);
{-MD5 of file, buf: buffer with at least bsize bytes} Das Ergebnis Digest ist ein Var-Parameter! Außerdem hast Du noch einen Error-Code Err, falls ein Fehler auftritt. Was willst Du mehr? Edit: Hier das ganze als Komplett-Programm (diesmal mit 32KB-Puffer)
Delphi-Quellcode:
und noch mal das 512MB-Testfile
{$Apptype console}
uses hash, md5, mem_util; const BSIZE = $8000; var buf: array[0..BSIZE-1] of byte; Digest: TMD5Digest; Err: word; begin if paramcount>0 then begin MD5File(paramstr(1),Digest, buf, sizeof(buf), Err); if Err<>0 then writeln('Error ', Err) else writeln('MD5 = ', HexStr(@Digest, sizeof(Digest))); end else writeln('Usage: MD5F <file>'); end.
Code:
D:\Work\CRC_HASH>timethis md5f.exe 512MB_A
TimeThis : Command Line : md5f.exe 512MB_A TimeThis : Start Time : Wed Nov 29 10:15:22 2017 MD5 = 31e4d9c6d74cd592b78f77f72965d6ab TimeThis : Command Line : md5f.exe 512MB_A TimeThis : Start Time : Wed Nov 29 10:15:22 2017 TimeThis : End Time : Wed Nov 29 10:15:24 2017 TimeThis : Elapsed Time : 00:00:02.610 |
AW: MD5-Prüfroutine für Delphi 10.2
Zitat:
Ok ich sehe, kein Stream mehr. Soweit ich das gerade sehe, kann MD5.MD5File aber nur Dateien mit einer maximalen Dateinamenlänge von 255 entgegennehmen. |
AW: MD5-Prüfroutine für Delphi 10.2
Zitat:
Zitat:
|
AW: MD5-Prüfroutine für Delphi 10.2
Hat das den alleinigen Grund MAX_PATH nicht zu übersteigen?
Das wäre doch mit \\?\ gelöst. |
AW: MD5-Prüfroutine für Delphi 10.2
Zitat:
Aber ich kann es gerne in die übernächste Version einbauen als
Delphi-Quellcode:
Die nächste Version ist unterwegs (heute oder morgen je nach Ablenkung) und bringt wesentlich beschleunigte Blake2B- und Blake2S-Routinen, Blake2B für alle Compiler von TP5 bis Tokyo.
procedure HashFile({$ifdef CONST} const {$endif} fname: String; PHash: PHashDesc;
var Digest: THashDigest; var buf; bsize: word; var Err: word); {-Calculate hash digest of file, buf: buffer with at least bsize bytes} |
AW: MD5-Prüfroutine für Delphi 10.2
Zitat:
Das \\?\ hänge jedenfalls ich immer vor meine Pfade. Es kommt zwar nicht so oft vor, dass ein Pfad MAX_PATH überschreitet, aber es kann schon vorkommen. P.S. kannst du ebenfalls bestätigen, dass Embarcaderos Fix gar kein Fix war? Denn wenn hash in den uses steht, wird nach System.Hash gesucht und nicht nach deiner Hash-Unit. Angeblich wurde das von Embarcadero ja behoben ... |
AW: MD5-Prüfroutine für Delphi 10.2
Zitat:
|
AW: MD5-Prüfroutine für Delphi 10.2
Ich musste erst Hash nach weHash umbenennen, sonst wird immer nach System.Hash gesucht.
Wenn ich die Units alle neu runterlade und nichts umbenenne, kompiliere kommt md5.pas(100): E2003 Undeklarierter Bezeichner: 'THashContext' Benenne ich Hash nach weHash um, ist alles gut. |
AW: MD5-Prüfroutine für Delphi 10.2
Zitat:
Zitat:
Das Projekt sieht dann so aus und compiliert ohne Probleme:
Delphi-Quellcode:
Delphi 10.2 Update 1 (Version 25.0.27659.1188)
program HashTest;
{$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, hash, md5; procedure Main; var context: THashContext; begin MD5Init(context); end; begin try Main; except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end. |
AW: MD5-Prüfroutine für Delphi 10.2
Zitat:
|
AW: MD5-Prüfroutine für Delphi 10.2
Zitat:
Code:
G:\CRC_HASH>G:\CRC_HASH\t_emb_we.dproj
G:\CRC_HASH>T_EMB_WE.exe Test hashing "abc" Using WE - CRC/Hash MD5 900150983cd24fb0d6963f7d28e17f72 SHA-256 ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad Using system.hash MD5 900150983cd24fb0d6963f7d28e17f72 SHA-256 ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad |
AW: MD5-Prüfroutine für Delphi 10.2
Ja ich denke die Lösung war einfach nur die Pfade zu den Hash-Dateien in die Suchpfade mit einzutragen, was ich vorher nie gemacht habe.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:32 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz