AGB  ·  Datenschutz  ·  Impressum  







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

String mit gzip (ent)zippen

Ein Thema von MatthiasR · begonnen am 26. Mär 2007 · letzter Beitrag vom 2. Apr 2009
Antwort Antwort
Seite 2 von 3     12 3      
Muetze1
(Gast)

n/a Beiträge
 
#11

Re: String mit gzip (ent)zippen

  Alt 26. Mär 2007, 18:36
Memo.Text kannst du der Funktion nicht übergeben, da es eine Property ist. Damit können dahinter Getter/Setter liegen (was hierbei auch der Fall ist) und der Funktion als Stringspeicherplatz eine Methode bzw. deren Code zu geben ist nicht vorteilhaft. Du musst mit Zwischenwerten als Strings arbeiten oder du nutzt den Delphi-Referenz durchsuchenTStringStream.
  Mit Zitat antworten Zitat
MatthiasR

Registriert seit: 21. Apr 2005
193 Beiträge
 
#12

Re: String mit gzip (ent)zippen

  Alt 19. Mär 2009, 10:30
2 Jahre sind vergangen und ich stehe wieder vor demselben Problem. Ich lese über ein Kartenterminal Daten von einer Smartcard ein (der eGK, wenns jemanden interessiert ), von denen es heißt, es handele sich um "gezippte XML-Dateien". "Die Basis für das Zippen ist die Software "gzip"."

Mit den bisher in diesem Thread genannten Lösungsansätzen hatte ich irgendwie kein Glück, bei der ZLib-Funktion erhalte ich wieder den Fehler "Ungültige Zeigeroperation". Ich habe auch schon die ZLib von hier ausprobiert und den Beispielcode auf meine Zwecke abgeändert, aber auch da erhalte ich einen Fehler.

Frage: gibt es irgendwo ein kleines Tool, das mir einen komprimierten String entpackt und anzeigt, damit ich sehen kann, ob die Daten, die ich versuche zu entpacken, überhaupt valide sind? Ich habe die gezippten Strings mal als txt-Dateien unten angehängt, vielleicht kann ja einer von euch mal sein Glück versuchen? Die Standard-Entpack-Programme erwarten solche Daten ja in einem entsprechenden Archiv mit Dateiheader usw. die bringen mich da wohl nicht wirklich weiter.

Vielen Dank schonmal im Voraus!
Angehängte Dateien
Dateityp: txt gezipptedaten2_800.txt (1,2 KB, 32x aufgerufen)
Dateityp: txt gezipptedaten_554.txt (850 Bytes, 23x aufgerufen)
  Mit Zitat antworten Zitat
gammatester

Registriert seit: 6. Dez 2005
999 Beiträge
 
#13

Re: String mit gzip (ent)zippen

  Alt 19. Mär 2009, 11:44
Das sind keine gültigen gzip-Files gemäß gzip-spec, denn sie beginnen nicht mit $1f $8b, obwohl diese beiden gzip-ID-Bytes ziemlich am Anfang der Dateien zu finden sind.

Was bedeutet denn genau:
Zitat:
"Die Basis für das Zippen ist die Software "gzip"."
Sieht nach stiller Postaus: ich kenne jemanden, dessen Berater ziemlich sicher ist, einen Programmierer zu kennen, der gehört hat, daß das gzip ist.

Selbst wenn man die Bytes vor den ID-Bytes löscht, kommt nichts Gültiges raus, auch zpipe kommt nicht damit zurecht.

Gammatester
  Mit Zitat antworten Zitat
MatthiasR

Registriert seit: 21. Apr 2005
193 Beiträge
 
#14

Re: String mit gzip (ent)zippen

  Alt 19. Mär 2009, 13:22
Zitat von gammatester:
Was bedeutet denn genau:
Zitat:
"Die Basis für das Zippen ist die Software "gzip"."
Sieht nach stiller Postaus: ich kenne jemanden, dessen Berater ziemlich sicher ist, einen Programmierer zu kennen, der gehört hat, daß das gzip ist.
Die Formulierung stammt aus der Beschreibung des Kartenterminal-Hertstellers, wie die Daten von der Smartcard auszulesen sind. Und sie ist in der Tat nicht wirklich aussagekräftig, daher habe ich sie auch einfach nur im O-Ton wiedergegeben.

Danke dass du dir die Mühe gemacht hast, die Dateien mal etwas unter die Lupe zu nehmen. Ich sehe dadurch nun zwei Möglichkeiten:

1. Was ich von der Karte ausgelesen habe, war schlichtweg Murks, der sich gar nicht erst dekomprimieren lässt.

2. Was ich von der Karte ausgelesen habe, war KEIN Murks, bedarf aber vor dem Dekomprimieren noch einer (oder diverser) Überarbeitung(en), wie Header abschneiden, Trailer abschneiden, mit 4711 multiplizieren oder weiß der Teufel.

3. Der Karteninhalt ist unbrauchbar, was ich aber bereits ausschließen kann, da das Kartenterminal auf seinem eingebauten Display bereits einige Daten der Karte anzeigen kann. Es muss es also selbst bereits geschafft haben, sie korrekt zu lesen und die Daten zu dekomprimieren.

Ich habe auch mal den Kartenterminal-Hersteller kontaktiert, ob die mir da weiterhelfen können. Vielleicht sehen die den Fehler auf Anhieb...
  Mit Zitat antworten Zitat
MatthiasR

Registriert seit: 21. Apr 2005
193 Beiträge
 
#15

Re: String mit gzip (ent)zippen

  Alt 23. Mär 2009, 09:01
Also: wie gammatester und ich eindeutig festgestellt haben, handelt es sich bei den von mir ausgelesenen Daten um valide gzip-Konstrukte, lediglich mit einem zusätzlichen Header vor dem gzip-Header '0x1F8B08'. Schneidet man diesen ab und speichert den verbleibenden String in einer Datei mit Endung ".gz", so kann man diese z.B. mittels 7zip entpacken.

Allerdings habe ich es immernoch nicht hingekriegt, den resultierenden gzip-String in meiner Anwendung mittels ZLib zu entpacken.

Der von himitsu gepostete Algorithmus
Delphi-Quellcode:
Uses ZLib;

Function CompressString(Input: String): String;
  Var Buffer: Pointer;
    BufSize: Integer;

  Begin
    Buffer := nil;
    Try
      CompressBuf(Input[1], Length(Input), Buffer, BufSize);
      SetLength(Result, BufSize);
      Move(Buffer^, Result[1], BufSize);
    Finally
      If Buffer <> nil Then FreeMem(Buffer);
    End;
  End;

Function DeCompressString(Input: String): String;
  Var Buffer: Pointer;
    BufSize: Integer;

  Begin
    Buffer := nil;
    Try
      DeCompressBuf(Input[1], Length(Input), 0, Buffer, BufSize);
      SetLength(Result, BufSize);
      Move(Buffer^, Result[1], BufSize);
    Finally
      If Buffer <> nil Then FreeMem(Buffer);
    End;
  End;
liefert mir bei DeCompressBuf immer eine ungültige Zeigeroperation. Was mache ich nur falsch???

Anbei noch die "richtigen" gzip-Dateien, vielleicht kann einer von euch nochmal sein Glück versuchen?!?

PS: Die resultierenden Daten sind reine Testdaten einer fiktiven Person, falls sich jemand Sorgen bezüglich des Datenschutz machen sollte .
Angehängte Dateien
Dateityp: gz versichertendaten_205.gz (848 Bytes, 30x aufgerufen)
  Mit Zitat antworten Zitat
Assertor

Registriert seit: 4. Feb 2006
Ort: Hamburg
1.296 Beiträge
 
Turbo C++
 
#16

Re: String mit gzip (ent)zippen

  Alt 29. Mär 2009, 21:32
Hi,

es gibt ein Update für zLibEx, welches nun nativ mit GZip umgehen kann (zLibExGZ). Vielleicht hilft das weiter.

Gruß Assertor
Frederik
  Mit Zitat antworten Zitat
MatthiasR

Registriert seit: 21. Apr 2005
193 Beiträge
 
#17

Re: String mit gzip (ent)zippen

  Alt 31. Mär 2009, 15:10
Habe ich gerade mal ausprobiert. Die Funktionen
Delphi-Quellcode:
{*****************************************************************************
*  GZDecompressStr                                                          *
*                                                                            *
*  pre-conditions                                                            *
*    s = compressed data string in gzip format                              *
*                                                                            *
*  post-conditions                                                          *
*    fileName  = filename                                                  *
*    comment    = comment                                                    *
*    dateTime  = date/time                                                  *
*                                                                            *
*  return                                                                    *
*    uncompressed data string                                                *
*****************************************************************************}


function GZDecompressStr(const s: AnsiString; var fileName,
  comment: AnsiString; var dateTime: TDateTime): String; overload;

function GZDecompressStr(const s: AnsiString): String; overload;
sollten ja eigentlich genau dafür gedacht sein, einen string im gzip-Format zu entpacken. Ich bekomme jedoch immer einen "data error", keinen blassen Schimmer, warum das nicht klappt. Ich übergebe die komprimierten Daten ab dem gzip-Header "#$1F#$8B" bis zum Ende der Daten (incl. der ganzen Nullen am Schluss).
  Mit Zitat antworten Zitat
Assertor

Registriert seit: 4. Feb 2006
Ort: Hamburg
1.296 Beiträge
 
Turbo C++
 
#18

Re: String mit gzip (ent)zippen

  Alt 31. Mär 2009, 16:08
Hi Infect,

Zitat von Infect:
function GZDecompressStr(const s: AnsiString; var fileName,
comment: AnsiString; var dateTime: TDateTime): String; overload;

function GZDecompressStr(const s: AnsiString): String; overload;[/delphi]
sollten ja eigentlich genau dafür gedacht sein, einen string im gzip-Format zu entpacken.
Das ist schonmal verkehrt. Du arbeitest mit Binärdaten, wenn Du die in einen AnsiString packen willst, muß Du bezüglich Codepages und automatischer Konvertierung (aka D2009) aufpassen.

Zitat von Infect:
Ich bekomme jedoch immer einen "data error", keinen blassen Schimmer, warum das nicht klappt. Ich übergebe die komprimierten Daten ab dem gzip-Header "#$1F#$8B" bis zum Ende der Daten (incl. der ganzen Nullen am Schluss).
Ja, nimm doch mal einen Stream stattdessen. Gerade mit Deinen Rohdaten getestet, geht einwandfrei...

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  InStream,
  OutStream: TMemoryStream;
begin
  InStream := TMemoryStream.Create;
  OutStream := TMemoryStream.Create;
  try
    InStream.LoadFromFile('D:\Downloads\VersichertenDaten.gz');
    InStream.Position := 0;
    GZDecompressStream(InStream, OutStream);
    OutStream.Position := 0;
    mmo1.Lines.LoadFromStream(OutStream); // mmo1 ist ein Memo auf dem Testform
  finally
    OutStream.Free;
    InStream.Free;
  end;
end;
Das ging jetzt aber in den Bereich "Grundlagen" von Delphi und hat wenig mit gzip zu tun

Gruß Assertor
Frederik
  Mit Zitat antworten Zitat
MatthiasR

Registriert seit: 21. Apr 2005
193 Beiträge
 
#19

Re: String mit gzip (ent)zippen

  Alt 1. Apr 2009, 10:42
Also zu allererstmal die Frohebotschaft, dass es nun endlich funktioniert! Ich habe vorher immer mit dem TStringStream gearbeitet, statt TMemoryStream, und das hat irgendwie nicht so funktioniert, wie ich mir das vorgestellt habe. Aber so, wie du es beschrieben hast, klappt es auch bei mir.

Nun aber zum Thema AnsiString und Binärdaten etc.: wenn das ganze Probleme mit Codepages usw. geben kann, wieso arbeiten dann die entsprechenden Kompressionsfunktionen mit den gleichen Datentypen?
Delphi-Quellcode:
{*****************************************************************************
*  GZCompressStr                                                            *
*                                                                            *
*  pre-conditions                                                            *
*    s          = uncompressed data string                                  *
*    fileName  = filename                                                  *
*    comment    = comment                                                    *
*    dateTime  = date/time                                                  *
*                                                                            *
*  return                                                                    *
*    compressed data string in gzip format                                  *
*****************************************************************************}


function GZCompressStr(const s: String; const fileName,
  comment: AnsiString; dateTime: TDateTime): AnsiString; overload;

function GZCompressStr(const s: String): AnsiString; overload;
Es wird ein ganz normaler String übergeben, der mit gzip komprimiert werden soll, und man erhält anschließend einen komprimierten AnsiString im gzip-Format, der ja auch nichts anderes als Binärdaten enthält, oder?!? Wo liegt der Denkfehler?

Aber erstmal Danke, dass du mir da auf die Sprünge geholfen hast, nun geht es endlich so, wie ich mir das vorgestellt habe!!!
  Mit Zitat antworten Zitat
Assertor

Registriert seit: 4. Feb 2006
Ort: Hamburg
1.296 Beiträge
 
Turbo C++
 
#20

Re: String mit gzip (ent)zippen

  Alt 1. Apr 2009, 11:37
Hi Infect,

Zitat von Infect:
Also zu allererstmal die Frohebotschaft, dass es nun endlich funktioniert! [...]
Aber so, wie du es beschrieben hast, klappt es auch bei mir.
[...]
Aber erstmal Danke, dass du mir da auf die Sprünge geholfen hast, nun geht es endlich so, wie ich mir das vorgestellt habe!!!
Das freut mich

Zitat von Infect:
Nun aber zum Thema AnsiString und Binärdaten etc.: wenn das ganze Probleme mit Codepages usw. geben kann, wieso arbeiten dann die entsprechenden Kompressionsfunktionen mit den gleichen Datentypen?

[...]

Es wird ein ganz normaler String übergeben, der mit gzip komprimiert werden soll, und man erhält anschließend einen komprimierten AnsiString im gzip-Format, der ja auch nichts anderes als Binärdaten enthält, oder?!? Wo liegt der Denkfehler?
Ja, die Funktionen sind auch richtig - es lassen sich ja auch prinzipiell Binärdaten in AnsiStrings erfassen.

Das Probleme ist aber: Wie bekommst Du die Daten unverändert in und aus dem String.

In Delphi 2009 wurde deswegen der RawByteString eingeführt, damit unter keinen Umständen Veränderungen am String durchgeführt werden. Dies erfolgt im Hintergrund durch die Festlegung der CodePage auf:

Delphi-Quellcode:
type
  RawbyteString = type AnsiString($ffff);
Genau darin liegt/lag aber das Problem von manchem Code vor Delphi 2009: Der AnsiString wurde zum Speichern von Daten verwendet, was sich bei der Umstellung von Source und Komponenten in Delphi 2009 rächte. Zwei Hauptprobleme dabei sind: 1) Konvertierung zur Laufzeit / Compiler-Magic und 2) die Länge von Chars (wegen der damalig festen Annahme von 1 Char = 1 Byte).

Bei jeder Zuweisung eines AnsiString kannst Du nicht sicher sein, daß die CodePage nicht abweicht und somit eine Konvertierung des Strings durchgeführt wird. Wenn der String nun Daten hält, werden diese ungültig.

Wenn Du, wie in meinem Beispielcode, direkt am Stream arbeitest umgehst Du diese Probleme.

Natürlich kannst Du auch eine Funktion schreiben, die die Daten in einem AnsiString/RawByteString einliest und dann die zLib Funktionen für AnsiStrings verwenden. Aber da wären einige Sachen wegen oben genannter Probleme zu beachten.

Gruß Assertor
Frederik
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


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 18:06 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