C# - как распаковать строку ISO-8859-1 - PullRequest
1 голос
/ 30 марта 2020

У меня есть C# программа, которая получила сжатый поток битов, полученный в наборе символов iso-8859-1. Мне нужно получить строку, которая была сжата. Он должен быть эквивалентен этому python коду:

zlib.decompress(bytes(bytearray(json_string, 'iso8859')), 15+32).

Я пробовал этот код для распаковки:

        Encoding iso_8859_1 = Encoding.GetEncoding("iso-8859-1");
        byte[] isoBytes = iso_8859_1.GetBytes(inputString);

        // then do GZip extract
        MemoryStream objMemStream = new MemoryStream();
        objMemStream.Write(isoBytes, 0, isoBytes.Length);
        objMemStream.Seek(0, SeekOrigin.Begin);

        GZipStream objDecompress = new GZipStream(objMemStream, CompressionMode.Decompress);

Но, objDecompress.Read не удалось, поэтому я сделал что-то не так.

***** Редактировать 31/03

Код Java, который выполняет сжатие:

    ByteArrayOutputStream out = new ByteArrayOutputStream();
    GZIPOutputStream gzip = new GZIPOutputStream(out);
    gzip.write(JsonStr.getBytes());
    gzip.close();
    return out.toString("ISO-8859-1");

Мне нужен код C#, чтобы получить JsonStr. Хотел бы получить помощь.

Ответы [ 2 ]

3 голосов
/ 02 апреля 2020

Есть встроенные классы DeflateStream GZipStream, но мне не удалось изменить это, вероятно, потому что ZLibNative имеет константы по умолчанию как public const int Deflate_DefaultWindowBits = -15. Есть обсуждения на эту тему, как в этой Do tNet проблема времени выполнения "System.IO.Compression для поддержки тонкой оболочки zlib поверх DEFLATE?"

Существует zlib.net Пакет NuGet, который вы можете использовать для распаковки данных. Вы можете прочитать о простой реализации сжатия / распаковки здесь Проблема сжатия и распаковки с zlib. Net.

Python сжатие

import zlib
import binascii

json_string = '{"aaaaaaaaaa": 1111111111, "bbbbbbbbbbb": "cccccccccccc"}'

compressed_data = zlib.compress(bytes(bytearray(json_string, 'iso8859')), 2)
decompressed_data = zlib.decompress(compressed_data, 15+32)

print('Compressed HEX data: %s' % (binascii.hexlify(compressed_data)))
print('Decompressed data: %s' % (decompressed_data))

Будет выводить:

Compressed HEX data: b'785eab564a8403252b054338d051504a4200a09452321250aa0500e4681153'
Decompressed data: b'{"aaaaaaaaaa": 1111111111, "bbbbbbbbbbb": "cccccccccccc"}'

C# распаковка

static void Main(string[] args) {
    var extCompressedHex = "785eab564a8403252b054338d051504a4200a09452321250aa0500e4681153";
    var extCompressed = HexStringToByteArray(extCompressedHex);

    byte[] extDecompressedData;
    DecompressData(extCompressed, out extDecompressedData);

    string extDecompressedJson = Encoding.GetEncoding("ISO-8859-1").GetString(extDecompressedData);

    Console.WriteLine("Hex ext compressed: {0}", ByteArrayToHex(extCompressed.ToArray()));
    Console.WriteLine("Raw ext decompressed: {0}", extDecompressedJson);
}


void DecompressData(byte[] inData, out byte[] outData)
{
    using (MemoryStream outMemoryStream = new MemoryStream())
    using (ZOutputStream outZStream = new ZOutputStream(outMemoryStream))
    using (Stream inMemoryStream = new MemoryStream(inData))
    {
        CopyStream(inMemoryStream, outZStream);
        outZStream.finish();
        outData = outMemoryStream.ToArray();
    }
}

// Helper functions ___________________________________________________

string ByteArrayToHex(byte[] bytes)
{
    StringBuilder sw = new StringBuilder();

    foreach (byte b in bytes)
    {
        sw.AppendFormat("{0:x2}", b);
    }

    return sw.ToString();
}

void CopyStream(System.IO.Stream input, System.IO.Stream output)
{
    byte[] buffer = new byte[2000];
    int len;
    while ((len = input.Read(buffer, 0, 2000)) > 0)
    {
        output.Write(buffer, 0, len);
    }
    output.Flush();
}

byte[] HexStringToByteArray(string hex)
{
    return Enumerable.Range(0, hex.Length)
                     .Where(x => x % 2 == 0)
                     .Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
                     .ToArray();
}

Будет выводить:

Hex ext compressed: 785eab564a8403252b054338d051504a4200a09452321250aa0500e4681153
Raw ext decompressed: {"aaaaaaaaaa": 1111111111, "bbbbbbbbbbb": "cccccccccccc"}

Вы можете проверить это, работая в этой . NET Fiddle .

1 голос
/ 09 апреля 2020

Я думаю, что так должно быть больше.

Encoding iso_8859_1 = Encoding.GetEncoding("iso-8859-1");
string inputData = "";
string outputData = "";

// then do GZip extract
using (MemoryStream uncompressedData = new MemoryStream())
using (GZipStream decompressor = new GZipStream(uncompressedData, CompressionMode.Decompress))
{
    byte[] inData = Encoding.ASCII.GetBytes(inputData);
    decompressor.Write(inData, 0, inData.Length);
    outputData = iso_8859_1.GetString(uncompressedData.ToArray());
}
...