Выполнить кодирование длины шестнадцатеричных строк, включая переводы строк - PullRequest
2 голосов
/ 12 августа 2010

Я реализую кодирование длины серии с использованием класса GZipStream в приложении winforms C #.

Данные предоставляются в виде последовательности строк, разделенных символами новой строки, например:

FFFFFFFF
FFFFFEFF
FDFFFFFF
00FFFFFF

Перед сжатием я преобразую строку в байтовый массив, но это не дает результатов, если присутствуют символы новой строки.

Каждая новая строка имеет значение, но я не уверен, как сохранить свою позицию в кодировке.

Вот код, который я использую для преобразования в байтовый массив:

private static byte[] HexStringToByteArray(string _hex)
{
    _hex = _hex.Replace("\r\n", "");
    if (_hex.Length % 2 != 0) throw new FormatException("Hex string length must be divisible by 2.");
    int l = _hex.Length / 2;
    byte[] b = new byte[l];
    for (int i = 0; i < l; i++)
    b[i] = Convert.ToByte(_hex.Substring(i * 2, 2), 16);
    return b;
}

Convert.ToByte выдает исключение FormatException, если символы новой строки не удаляются, с информацией: «Дополнительные непарсируемыесимволы находятся в конце строки. "Что меня не удивляет.

Как лучше всего убедиться, что символы новой строки могут быть правильно включены?

Примечание Я должен добавить, что сжатая версия этой строки сама должна быть строкой, которая может быть включена в документ XML.

Редактировать:

Я пытался просто преобразовать строкув байтовый массив без выполнения какого-либо двоичного преобразования на нем, но все еще возникают проблемы со сжатием.Вот соответствующие методы:

    private static byte[] StringToByteArray(string _s)
    {
        Encoding enc = Encoding.ASCII;
        return enc.GetBytes(_s);
    }

    public static byte[] Compress(byte[] buffer)
    {
        MemoryStream ms = new MemoryStream();
        GZipStream zip = new GZipStream(ms, CompressionMode.Compress, true);
        zip.Write(buffer, 0, buffer.Length);
        zip.Close();
        ms.Position = 0;

        byte[] compressed = new byte[ms.Length];
        ms.Read(compressed, 0, compressed.Length);

        byte[] gzBuffer = new byte[compressed.Length + 4];
        Buffer.BlockCopy(compressed, 0, gzBuffer, 4, compressed.Length);
        Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gzBuffer, 0, 4);
        return gzBuffer;
    }

Ответы [ 2 ]

2 голосов
/ 12 августа 2010

Во-первых: вы уверены, что простое сжатие текста не дает такого же результата, как сжатие "преобразованной в двоичную" форму?

Если вы хотите продолжить преобразование в двоичный файл, я могупредложите два варианта:

  • В начале каждой строки напишите число, указывающее, сколько байтов в строке.Затем, когда вы распаковываете, вы читаете и конвертируете столько байтов, а затем пишете новую строку.Если вы знаете , что каждая строка всегда будет иметь длину менее 256 байт, вы можете просто представить это как один байт.В противном случае вам может потребоваться больший фиксированный размер или некоторая кодировка переменного размера (например, «когда установлен верхний бит, он все еще является частью числа») - последний довольно быстро становится волосатым.
  • В качестве альтернативы "экранировать "новую строку, представив ее как (скажем) 0xFF, 0x00.Тогда вам также нужно будет избежать подлинного 0xFF, как, скажем, 0xFF 0xFF.Когда вы читаете данные, если вы читаете 0xFF, вы затем читаете следующий байт, чтобы определить, представляет ли он новую строку или подлинный 0xFF.

РЕДАКТИРОВАТЬ: я считаю, что ваш оригинальный подход был в корне ошибочным,Все, что вы получаете из GZipStream, это , а не текст, и не должно рассматриваться как текст, использующий Encoding.Однако вы можете легко превратить его в текст ASCII, вызвав Convert.ToBase64String.Кстати, еще один трюк, который вы пропустили, - это позвонить по номеру ToArray на MemoryStream, что даст вам содержимое в виде byte[] без лишних проблем.

0 голосов
/ 12 августа 2010

Если опубликованные вами данные являются репрезентативными для всех данных, то у вас есть новая строка каждые 4 байта, поэтому, если вам это нужно при обратном преобразовании, просто вставьте один из каждых 4 байтов данных

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...