#1 2024-11-04 16:20:14

ebekman
Member
Registered: 2024-11-04
Posts: 4

SynZip in c#

Hi,

I'm a C# developer and works now in a integration between two companies.

Last week I build the query to read data from source database to send to API on my side.
Then and I noticed this "base64" information on a text field.

This field should have a XML information about sales TAX and the size is about a few Kb.

Talking with the IT of this system about how to "decode" this data back to XML.

They told me that the XML was compressed by application before store in database.
The application has no more developer (an orphan app) and no source code.
And in a "very long time ago" the developer build a small program to "decompress" this data One by one using ctrl-c + ctrl-v.

I pass this small program in a EXE analyser ans noticed references to SynZipStringDecompress, then a google it and found SynZip.pas

/// low-level access to ZLib compression (1.2.5 engine version)
// - this unit is a part of the freeware Synopse framework,
// licensed under a MPL/GPL/LGPL tri-license; version 1.18

I try to use ZLib Library to .net but a got error, i try some online string decompressor with no success too.
The error is always header relative.

Below has one of the "compressed string" in this database and the respective decompressed data (a XML).

Compressed string
Original XML

Plase give some north to follow how I decompress this data in C#.


Thank in advance.

Last edited by ebekman (2024-11-04 16:49:42)

Offline

#2 2024-11-04 16:23:25

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,661
Website

Re: SynZip in c#

Please follow the forum rules and don't post such huge content in the forum thread themselves.

Use a gist for instance instead.

Offline

#3 2024-11-04 16:37:21

ebekman
Member
Registered: 2024-11-04
Posts: 4

Re: SynZip in c#

ab wrote:

Please follow the forum rules and don't post such huge content in the forum thread themselves.

Use a gist for instance instead.


Poste edited, gist created and linked.

But, IMHO this pratice of take a part the post and associated info, creates in a near future a Link rot
That harm the spread of information to others. And multiply the necessity of post duplication.

I only express my vision and concerns, i'll respect the forum rules.

Thank for advice

Last edited by ebekman (2024-11-04 16:59:47)

Offline

#4 2024-11-05 02:43:03

zen010101
Member
Registered: 2024-06-15
Posts: 66

Re: SynZip in c#

program demoUncompressString;
uses
  mormot.core.buffers,
  mormot.core.zip;

const
  b64Buffer = 'ZxsAA....==';
var
  binBuffer: RawByteString;
  xmlStr: RawByteString;
begin
  binBuffer := Base64ToBin(b64Buffer);
  xmlStr := UncompressString(binBuffer);
  ...
end.

It very simple task.

Offline

#5 2024-11-05 03:32:18

zen010101
Member
Registered: 2024-06-15
Posts: 66

Re: SynZip in c#

The following c# code is just an example and does not mean that it can be executed:

https://gist.github.com/zen010101/e8236 … c34777b9ee

Offline

#6 2024-11-05 18:06:09

ebekman
Member
Registered: 2024-11-04
Posts: 4

Re: SynZip in c#

zen010101 wrote:

The following c# code is just an example and does not mean that it can be executed:

https://gist.github.com/zen010101/e8236 … c34777b9ee

I build a new projetct with code that you presented and I got "Header checksum illegal"

      string base64Data = "ZxsAAAAAAADKtNCXx...";
      byte[] data = Convert.FromBase64String(base64Data);
      CompressionHelper.UncompressString(data);

At first I download the ICDharpCode.SharpZipLib compiled from Nuget, but now I put the whole project (SharpZipLib) in the solution.


What I understand until now:
The 12 first bytes in the binary (after base 64 convertion) is the header an in hex is: 67 1B 00 00 00 00 00 00 CA B8 D0 97
  First 8 bytes is original size 0x1B67 => 7015 Its exactly the size of original XML.
  Last 4 bytes is checksum 97 D0 B8 CA

The next 2 bytes is the header of zlib 0xC5 0x39. The zlib documentation says that SUM of this two bytes it must be exactly divisible by 31 (% 31)
At this part "Header checksum illegal" error is raised.

Im stuck in this point

Offline

#7 2024-11-05 20:16:53

danielkuettner
Member
From: Germany
Registered: 2014-08-06
Posts: 357

Re: SynZip in c#

@ebekman Congrats, you're almost there! SynZip is able to decompress your data. The pascal example from @zen010101 is working.

Now you need somebody who create a pascal .dll/.so for you that can be called from your c#.

Offline

#8 2024-11-06 03:29:07

zen010101
Member
Registered: 2024-06-15
Posts: 66

Re: SynZip in c#

ebekman wrote:

The next 2 bytes is the header of zlib 0xC5 0x39. The zlib documentation says that SUM of this two bytes it must be exactly divisible by 31 (% 31)
At this part "Header checksum illegal" error is raised.

Im stuck in this point

Using https://github.com/jzebedee/LibDeflate.NET instead of zlib to Uncompress the data.

Offline

#9 2024-11-06 14:43:13

ebekman
Member
Registered: 2024-11-04
Posts: 4

Re: SynZip in c#

zen010101 wrote:

Using https://github.com/jzebedee/LibDeflate.NET instead of zlib to Uncompress the data.


Tanks Zen,

Works as a charm.

Here is my code:

using System;
using System.Text;
using LibDeflate;
using System.Buffers;
...
    //-------------------------------------------------------------------------
    //| Decompress zlib string                                                |
    //-------------------------------------------------------------------------
    public static string DecompressString(string base64Data) {
      //Input                                                                 '
      byte[] compressedData = Convert.FromBase64String(base64Data);
      //Get original length                                                   '
      int uncompressedLength = BitConverter.ToInt32(compressedData, 0);
      //Input span                                                            '
      Span<byte> inputSpan = compressedData.AsSpan(12);
      //Output span                                                           '
      byte[] decompressedData = new byte[uncompressedLength];
      Span<byte> outputSpan = new Span<byte>(decompressedData);
      //Decompressing                                                         '
      using(Decompressor decompressor = new DeflateDecompressor()) {
        OperationStatus status = decompressor.Decompress(inputSpan, outputSpan, out int decompressSize);
        if(status != OperationStatus.Done) { throw new Exception(status.ToString()); }
        if(decompressSize != uncompressedLength) { throw new Exception("Decompress size error"); }
      }
      //Return                                                                '
      return Encoding.UTF8.GetString(outputSpan.ToArray());
    }

There is a 'jump of the cat' on the LibDeflate.Net (its a local expression for "there's a trick" or "there's a secret")

After append the LibDeflate.Net into project using the Nuget, I got an error that the libdeflate.dll (libdeflate.Native) not found.
The trick is not reference this DLL, but add into project and alter the proprety "Copy to output directory" to "Copy Always" or "Copy if newer".


Thank again.

Offline

Board footer

Powered by FluxBB