Декодирование строки Z64 (ZB64) - PullRequest
0 голосов
/ 16 октября 2019

Я работаю над разбиением определений этикеток ZPL, сгенерированных программным обеспечением создания этикеток NiceLabel. По большей части мне не нужно беспокоиться о декодировании Z64, потому что это просто кодированная графика, и мне не нужно изменять базовые данные.

Однако у меня есть строка текста, которая используется какграфика по метке по какой-то причине, вероятно, из-за шрифта или чего-то в этом роде.

В любом случае строка Z64 или ZB64 создается путем сжатия исходных данных с использованием LZ77 и кодирования их как Base64, а затем добавления CRC в конце.

ПРИМЕР ТЕСТОВОЙ СТРОКИ:

:Z64:eJztkDFOxDAQRb81hRsULmBtruECyRwpZYpFGLmg5AhwFKMUuYal9CtL26QwHsbe3RMguv3lz9P85wD3/CWaiZ+56OjqWA44cwKIAyfeXXL1sQ7YWqd54czltTge+VOdOQsXFp8TrLUw9KEW3+6pLU4Zk3mC0ataonSEzU8JMywGCiFcue+c8YLGvYcLF5a+68WFhbvtRs5jdmVkWolj96vgXe/it7eucT+0+gxV5N5RrdTveQpevhnxO+BEfRe0xIzc/EbUzkn3lhLSIH6DdFeu+c39Hb7c7vksfrJryB8vu6A4cxE/NjpK1/6LkJZ3+nL1gaLt3D33/Ed+AehfkrY=:6C38

ПРИМЕР ТЕСТА СТРОКИ:

eJztkDFOxDAQRb81hRsULmBtruECyRwpZYpFGLmg5AhwFKMUuYal9CtL26QwHsbe3RMguv3lz9P85wD3/CWaiZ+56OjqWA44cwKIAyfeXXL1sQ7YWqd54czltTge+VOdOQsXFp8TrLUw9KEW3+6pLU4Zk3mC0ataonSEzU8JMywGCiFcue+c8YLGvYcLF5a+68WFhbvtRs5jdmVkWolj96vgXe/it7eucT+0+gxV5N5RrdTveQpevhnxO+BEfRe0xIzc/EbUzkn3lhLSIH6DdFeu+c39Hb7c7vksfrJryB8vu6A4cxE/NjpK1/6LkJZ3+nL1gaLt3D33/Ed+AehfkrY=

Мой код для декодирования / распаковки:

static string DecompressZb64(string compressedString)
{
    var b64 = SmartWarehouse.Shared.Utils.Parser.ConvertFromBase64(compressedString);
    var encoding = new ASCIIEncoding();
    var inBytes = Encoding.ASCII.GetBytes(b64);
    var outBytes = new byte[inBytes.Length];
    try
    {
        using (var memoryStream = new MemoryStream())
        using (var decompressionStream = new DeflateStream(memoryStream, CompressionMode.Decompress))
        {
            decompressionStream.Read(outBytes, 0, inBytes.Length);
        }

        return encoding.GetString(outBytes);
    }
    catch (Exception e)
    {
        // TODO: DOcument exception
        Console.WriteLine(e.Message);
    }

    return string.Empty;
}

Текущее исключение:

Block length does not match with its complement.

Stacktrace:

   at System.IO.Compression.Inflater.DecodeUncompressedBlock(Boolean& end_of_block)
   at System.IO.Compression.Inflater.Decode()
   at System.IO.Compression.Inflater.Inflate(Byte[] bytes, Int32 offset, Int32 length)
   at System.IO.Compression.DeflateStream.Read(Byte[] array, Int32 offset, Int32 count)
   at SmartWarehouse.Tools.Program.DecompressZb64(String compressedString) in C:\Users\[user_dir]\Source\Repos\Handheld.[user].[fork]\SmartWarehouse.Tools\Program.cs:line 511

ОБНОВЛЕНИЕ:

Я искал это и нашел ТАК сообщение этоэто по сути та же проблема. Поэтому я провел еще несколько исследований и нашел эту статью в блоге 2007 года . В котором обсуждается обходной путь, пропускающий первые 2 байта во входном массиве, поскольку эти байты фактически не включены в спецификацию RFC.

ИЗМЕНЕНИЕ КОДА:

static string DecompressZb64(string compressedString)
{
    var b64 = Convert.FromBase64String(compressedString);
    var encoding = new ASCIIEncoding();
    var outBytes = new byte[b64.Length - 2];
    try
    {
        using (var memoryStream = new MemoryStream(b64))
        {
            memoryStream.ReadByte();
            memoryStream.ReadByte();
            using (var decompressionStream = new DeflateStream(memoryStream, CompressionMode.Decompress))
            {
                decompressionStream.Read(outBytes, 0, b64.Length - 2);
            }
        }

        return encoding.GetString(outBytes);
    }
    catch (Exception e)
    {
        // TODO: DOcument exception
        Console.WriteLine(e.Message);
    }

    return string.Empty;
}

Это изменение кода не 'Фактически, оно больше не генерирует исключение, однако оно не распаковывается должным образом и возвращает следующий результат:

"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"

1 Ответ

1 голос
/ 16 октября 2019

Эти данные выглядят нормально для меня, я получил это изображение:

image

Это монохромное растровое изображение, один бит на пиксель.

Ваш код не считывался до конца потока, на самом деле существует 1280 байтов данных изображения, которые затем можно декодировать на изображении выше.

...