![]() |
Encrypted ZipFile
Hallo zusammen,
ich verwende für meine Projekte u.a. die Encrypted ZipFile Quellen von Uwe Raabe zum Verschlüsseln von Zip-Dateien (an dieser Stelle besten Dank dafür!). ![]() Leider scheitere ich derzeit am Entpacken einer Datei von der Größe von 164.581.376 Bytes. Die verschlüsselte Zip Datei an sich ist 231.569.548 Bytes groß. Ich erhalte beim Entpacken einen Stream Lesefehler. Die Datei wird bis zur Größe von 164.536.320 Bytes ohne Probleme entpackt. Vergleiche ich die Dateien binär, stimmen die Inhalte bis zur entsprechenden Größe überein. Nur der Rest fehlt. Ich vermute das Problem beim ineffizenten Seek, wie auch im Blog-Post beschrieben: Zitat:
Delphi-Quellcode:
Vielleicht hat der ein oder andere eine Idee, wie man das Problem lösen könnte. Eine Testdatei hätte ich auch zur Verfügung, aber ich denke das lässt sich auch mit der anderen größeren Datei reproduzieren.
function TDecryptStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
var curPos: Int64; newPos: Int64; begin curPos := FStream.Position; newPos := CurPos; case Origin of soBeginning: newPos := Offset; soCurrent: newPos := curPos + Offset; soEnd: newPos := FStreamSize + Offset; end; if newPos < curPos then begin ResetStream; result := Skip(newPos); end else begin result := Skip(newPos - curPos); end; end; Viele Grüße und bleibt gesund! |
AW: Encrypted ZipFile
Hallo WiPhi,
Ich bin auf genau das selbe Problem gestoßen. Allerdings ging es bei mir um viele kleine Dateien. Wie du auch, vermutete ich das Problem im
Code:
des
Seek
Code:
.
TDecryptStream
Ich habe die Implementierung folgendermaßen angepasst:
Code:
Der Originalcode in
function TDecryptStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
var curPos: Int64; newPos: Int64; begin curPos := FStream.Position; newPos := CurPos; case Origin of soBeginning: newPos := Offset; soCurrent: newPos := curPos + Offset; soEnd: newPos := FStreamSize + Offset; end; if newPos < curPos then begin // ResetStream; // result := Skip(newPos); FStream.Position := FStreamStartPos + newPos; result := FStream.Position; end else begin result := Skip(newPos - curPos); end; end;
Code:
ist auskommentiert und durch die beiden neuen Zeilen im Block ersetzt.
newPos < curPos
Ich habe es auch mit einigen großen ca. 10MB und einer 290MB großen Datei getestet. Bei mir funktioniert der Aufruf von
Code:
mit dem Index der Datei und einem Byte Array.
aZipFile.Read(aZipFileIndex, aBytes)
Nebeneffekt ist, dass die Dekomprimierung nicht merklich langsamer wird, je mehr aus dem Zip File gelesen wird. Zumindest in dem umgeschriebenen Abschnitt wird der von Uwe Raabe erwähnte Brute Force Ansatz vermieden. Vielleicht hilft es dir auch. Vielen Dank auch an Uwe Raabe für die Quellen. Gruß fux!!! |
AW: Encrypted ZipFile
Ich hoffe ja die machen das im Setter von Position richtig. (sollten/müssten sie eigentlich, und da es funktioniert, scheint es so).
Das Problem ist ja, dass man die Verschlüsselung nicht rückwärts laufen lassen kann. * Beim Sprung vorwärts kann einfach das dazwischen gelesen werden, um die Verschlüsselung fortzuführen. * Beim Sprung zurück bleibt nur die Möglichkeit zum Anfang zu springen, alles zurückzusetzen und wieder bis zur neuen Position zu lesen, um die Verschlüssekung auf diese Stelle zu schieben. Man könnte das jetzt noch optimieren, indem man Marker erstellen lässt, bzw. regelmäßig welche einfügt, also an gewissen Stellen sich Position+ZustandDerVerschlüsselung speichert, womit man dann "schnell" zu diesen Positionen springen, die Verschlüsselung zurückzusetzen und dort fortfahren zu können, ohne immer wieder komplett zum Anfang zurück zu müssen. Im Prinzip macht ResetStream+Skip ja eigentlich alles richtig ... k.A. warum es damit Probleme gibt. Einzig, was ich mir vorstellen kann, bei über 2 GB (hab nicht nachgesehn), dass Skip nicht mit 64 Bit arbeitet und dann die falsche Position anspringt (Integerüberlauf). |
AW: Encrypted ZipFile
Zitat:
Vielen Dank! |
AW: Encrypted ZipFile
Zitat:
Zitat:
|
AW: Encrypted ZipFile
Ich kann momentan auch nicht erklären, was mit dem Originalcode nicht funktioniert. Meine ersten Gedanken gingen in Richtung Integerüberlauf oder ein Problem durch 32-64 Bit Integer. Uwes Blogpost ist ursprünglich von 2017. Ich habe mehrere Stunden damit zugebracht, die vermuteten Probleme zu bestätigen. Leider war ich damit nicht erfolgreich. Der Code sollte genau so funktionieren, wie Uwe beschrieben hat.
Meine Änderung war am Ende nur noch ein Notgriff, der bislang funktioniert. Ich bin auch sicher, dass Uwes Code in 2017 mit einer früheren Delphi Version funktioniert hat. Vielleicht ist der hier aufgetretene Fehler nur eine Folge eines anderen Problems in TZipFile in der aktuellen Delphi Version. Was in zukünftigen Versionen passiert sollte man genau im Auge haben. Viele Grüße an alle - und bleibt gesund! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:16 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 by Thomas Breitkreuz