Einzelnen Beitrag anzeigen

WiPhi

Registriert seit: 19. Feb 2015
90 Beiträge
 
Delphi 11 Alexandria
 
#1

Encrypted ZipFile

  Alt 21. Mär 2020, 21:19
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!).
https://www.uweraabe.de/Blog/downloa...cryptedzipfile

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:
One of the problems I encountered was the fact that the original TZipFile implementation uses Seek during decrytion to rewind the stream to a previous position. This didn’t any harm in the previous part as we used a memory stream there, but here we don’t have this luxury. Just moving the stream position will not work in this case because the decryption algorithm uses a state which is updated with each byte decrypted.

The current implementation uses a brute force approach and re-reads the whole stream from the beginning when a Seek wants to move backwards. This may be optimized for better performance in a future implementation.
https://www.uweraabe.de/Blog/2017/03...yption-part-2/
Beim Debuggen stellte ich fest, dass er bei der TDecryptStream.Seek Funktion von vorn zu suchen beginnt und das Skip dazu führt, dass er anschließend mit ReadBuffer 0 Bytes einliest, was zur Exception führt.

Delphi-Quellcode:
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;
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.

Viele Grüße und bleibt gesund!
Wer sucht, der findet. Wer länger sucht, findet mehr.
  Mit Zitat antworten Zitat