Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi GZip-Stringinhalt extrahieren (https://www.delphipraxis.net/216115-gzip-stringinhalt-extrahieren.html)

rdeutsch 30. Okt 2024 15:38

GZip-Stringinhalt extrahieren
 
Hallo

Ich haben einen String mit einem gzip-komprimierten Inhalt. Dieser Stringinhalt soll nun als "lesbaren" String extrahiert werden.

Beispiel:
Inhalt gzip-String : H4sIAAAAAAAAA/NIzMnJVwhJrSgBAM5sM2wKAAAA
Extrahierter String: Hallo Text

Leider sind alle meine bisherigen Versuche kläglich gescheitert.

z.B. myDecompressedString := zlib.ZDecompressStr(BytesOf('H4sIAAAAAAAAA/NIzMnJVwhJrSgBAM5sM2wKAAAA')) resultiert in einer Fehlermeldung "... Exception der Klasse EZDecompressionError mit der Meldung 'data error' aufgetreten."

Kann mir hier jemand weiterhelfen bzw. was mache ich falsch?

Danke im Voraus und Grüsse,
Robert

himitsu 30. Okt 2024 15:47

AW: GZip-Stringinhalt extrahieren
 
Diese Delphi-Funktionen sind "andersrum".

Delphi-Referenz durchsuchenZCompressStr = einen "String" komprimieren und binär (TBytes) rausgeben
Delphi-Referenz durchsuchenZDecompressStr = dieses Binäre wieder in einen "String" dekomprimieren

Du hast hier aber Base64-kodierte Daten, mit irgendeinem Payload davor.

Fazit:
* erst dieses Base64 in ein TBytes konvertieren
* welches du anschließend dekomrimieren kannst

rdeutsch 31. Okt 2024 08:56

AW: GZip-Stringinhalt extrahieren
 
Danke dir, aber leider erhalte ich immer noch den "data error"-Fehlermeldung beim Aufruf von ZDecompressStr(myBytes).

Code:
myDecompressedString := DecompressBase64GZipString('H4sIAAAAAAAAA/NIzMnJVwhJrSgBAM5sM2wKAAAA');

function DecompressBase64GZipString(Value: String): String;
var myBytes: TBytes;
begin
  myBytes := System.NetEncoding.TNetEncoding.Base64.DecodeStringToBytes(Value);
  result := zLib.ZDecompressStr(myBytes);
end;
Wenn ich den Stringinhalt 'H4sIAAAAAAAAA/NIzMnJVwhJrSgBAM5sM2wKAAAA' z.B. auf https://codebeautify.org/gzip-decompress-online eingebe, klappt problemlos.

Was mache ich da falsch?

Rolf Frei 31. Okt 2024 13:04

AW: GZip-Stringinhalt extrahieren
 
Ich vermute da wird versucht mit deflate zu dekomprimieren.

Schau dir mal die System.ZLib.TZDecompressionStream.Create Funktion an. Da gibt es einen Parameter WindowsBits, der steuert, dass man gzip benötigt. Siehe auch die Hilfe dazu unter: https://docwiki.embarcadero.com/Libr...nStream.Create

Hier ist noch ein Blog zu diesem Thema: https://blog.dummzeuch.de/2023/07/27...ion-in-delphi/

rdeutsch 31. Okt 2024 14:46

AW: GZip-Stringinhalt extrahieren
 
Yes, deine Vermutung war richtig. WindowsBits und der Blog von dummzeuch hat mir auf die Sprünge geholfen. :lol:

Mit untenstehendem Code klappt die Umwandlung von 'H4sIAAAAAAAAA/NIzMnJVwhJrSgBAM5sM2wKAAAA' nach 'Hallo Text' wunderbar.

Vielen Dank für eure Hilfe.:cheers::cheers:

Code:
function DecompressGzipBase64(Value: string; parUseGZip: boolean): string;
var WindowBits: Integer;
    Bytes: TBytes;
    BytesStream: TBytesStream;
    DecompressionStream: TZDecompressionStream;
    OutStream: TMemoryStream;
    resText : AnsiString;
begin
  result := '';
  WindowBits := 15;
  if parUseGZip then WindowBits := WindowBits + 16;

  // base64-String decodieren und in Bytearray ablegen
  Bytes := TNetEncoding.Base64.DecodeStringToBytes(Value);

  // Inhalt des Bytearrays extrahieren
  DecompressionStream := nil;
  BytesStream := TBytesStream.Create(Bytes);
  try
    OutStream := TMemoryStream.Create();
    DecompressionStream := TZDecompressionStream.Create(BytesStream, WindowBits);
    DecompressionStream.Position := 0;
    OutStream.CopyFrom(DecompressionStream, 0);
    OutStream.Position := 0;
    SetLength(resText, OutStream.Size);
    OutStream.Read(resText[1], OutStream.Size);
  finally
    BytesStream.Free;
    DecompressionStream.Free;
    OutStream.Free;
  end;
  result := resText;
end;

dummzeuch 31. Okt 2024 17:53

AW: GZip-Stringinhalt extrahieren
 
Es freut mich zu hören, dass mein Blog-Post auch anderen hilft. Ich bin immer unsicher, ob es sinnvoll ist, solche Sachen zu posten.

Hauptsächlich mache ich das wirklich, damit ich es später per Google finde, falls ich dasselbe Problem irgendwann nochmal habe und dann den Post schon längst vergessen habe. Das ist schon mehrfach passiert. Vielleicht werde ich alt, oder ich mache einfach zu viele unterschiedliche Sachen (gerade mal wieder Perl Programmierung. Das ist sowas von primitiv, wenn man Delphi gewohnt ist.)

himitsu 31. Okt 2024 19:26

AW: GZip-Stringinhalt extrahieren
 
Aber warum kommt da ein Datenfehler?

Delphi-Quellcode:
uses System.NetEncoding, System.ZLib;

procedure TForm2.FormCreate(Sender: TObject);
var
  myBytes, myText: TBytes;
begin
  const Value = 'H4sIAAAAAAAAA/NIzMnJVwhJrSgBAM5sM2wKAAAA';
  myBytes := TNetEncoding.Base64.DecodeStringToBytes(Value);
  ZDecompress(myBytes, myText); // <<<<<<<<
  //...
end;
Ob als Stream oder Bytes, sollte doch keinen Unterschied machen. :gruebel:


[add] Ahhh, die Bits.

Zitat:

WindowBits + 16
Wenn das Bits sind, müsste es dann nicht OR anstatt + sein?
(auch wenn es HIER zufällig passt)


OK, steht in der Hilfe ... 8 bis 15
und z.B. "add 16" für spezielles GZip-Zeugs.

Anzahl der Bits ... nicht selbst eine BitMaske.

Delphi-Quellcode:
WindowBits := $0F;
if parUseGZip then WindowBits := $1F;
//if parUseGZip then WindowBits := WindowBits or $10;

WindowBits := %0000_1111;
if parUseGZip then WindowBits := %0001_1111;
//if parUseGZip then WindowBits := WindowBits or %0001_0000;


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:17 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