AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Encrypted ZipFile

Ein Thema von WiPhi · begonnen am 21. Mär 2020 · letzter Beitrag vom 3. Apr 2020
Antwort Antwort
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
fux75

Registriert seit: 31. Mär 2020
2 Beiträge
 
#2

AW: Encrypted ZipFile

  Alt 31. Mär 2020, 11:33
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:
Seek
des
Code:
TDecryptStream
.

Ich habe die Implementierung folgendermaßen angepasst:

Code:
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;
Der Originalcode in
Code:
newPos < curPos
ist auskommentiert und durch die beiden neuen Zeilen im Block ersetzt.

Ich habe es auch mit einigen großen ca. 10MB und einer 290MB großen Datei getestet. Bei mir funktioniert der Aufruf von
Code:
aZipFile.Read(aZipFileIndex, aBytes)
mit dem Index der Datei und einem Byte Array.
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!!!
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.132 Beiträge
 
Delphi 12 Athens
 
#3

AW: Encrypted ZipFile

  Alt 31. Mär 2020, 11:52
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).
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (31. Mär 2020 um 11:54 Uhr)
  Mit Zitat antworten Zitat
WiPhi

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

AW: Encrypted ZipFile

  Alt 2. Apr 2020, 15:59
Hallo WiPhi,

Der Originalcode in
Code:
newPos < curPos
ist auskommentiert und durch die beiden neuen Zeilen im Block ersetzt.
Genial, damit scheint es zu funktionieren! Erste Tests sehen vielversprechend aus.

Vielen Dank!
Wer sucht, der findet. Wer länger sucht, findet mehr.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.006 Beiträge
 
Delphi 12 Athens
 
#5

AW: Encrypted ZipFile

  Alt 2. Apr 2020, 16:24
Genial, damit scheint es zu funktionieren! Erste Tests sehen vielversprechend aus.
Das solltest du aber nochmal genau überprüfen, denn:
Zitat:
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.
Allerdings ist der Code auch noch nicht für die aktuelle Delphi-Version getestet.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
fux75

Registriert seit: 31. Mär 2020
2 Beiträge
 
#6

AW: Encrypted ZipFile

  Alt 3. Apr 2020, 07:44
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!
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:25 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz