1: 1 декодирование октетов UTF-8 для визуализации

1

Я делаю инструмент (С#, WPF) для просмотра двоичных данных, которые могут содержать встроенный текст. Для таких пользователей данных традиционно использовать два вертикальных столбца, один из которых отображает шестнадцатеричное значение каждого байта, а другой - символ ASCII, соответствующий каждому байту, если он доступен для печати.

Я думал, что было бы неплохо поддерживать отображение встроенного текста с использованием кодировок, отличных от ASCII, в частности UTF-8 и UTF-16. Проблема в том, что кодовые точки UTF не отображают 1:1 с октетами. Я хотел бы сохранить выравнивание выходной сетки в соответствии с ее расположением в данных, поэтому мне нужно, чтобы каждый октет отображал что-то для отображения в соответствующей ячейке в сетке. Я думаю, что конечный октет каждой кодовой точки будет отображаться на получаемый символ Юникода и выводит карту байтов на заполнители, которые различаются по длине последовательности (возможно, кружили формы и используют цвет, чтобы отличать их от фактических закодированных символов), и продолжения и недопустимые байты аналогично заполнителям.

struct UtfOctetVisualization
{
    enum Classification 
    { 
       Ascii, 
       NonAscii, 
       LeadByteOf2, 
       LeadByteOf3, 
       LeadByteOf4, 
       Continuation, 
       Error
    }

    Classification OctetClass;
    int CodePoint; // valid only when OctetClass == Ascii or NonAscii
}

Метод Encoding.UTF8.GetString() не предоставляет никакой информации о местоположении, из которого получен результирующий символ.

Я мог бы использовать Encoding.UTF8.GetDecoder() и call Convert передавать один байт за раз, чтобы completed выходной параметр выдавал классификацию для каждого октета.

Но в обоих методах, чтобы иметь обработку недопустимых символов, мне нужно было бы реализовать класс DecoderFallback? Это выглядит сложным.

Есть ли простой способ получить эту информацию с помощью API, поставляемых с.NET (в System.Text или иначе)? Используя System.Text.Decoder, как бы выглядел этот резервный образ, который заполняет выходной массив, разделяемый с декодером?

Или более возможно написать пользовательский распознаватель UTF-8 (конечный автомат)?

  • 0
    Как вы собираетесь отличать случайный бинарный мусор от подлинного контента Unicode? Есть много вещей, которые будут казаться законными, особенно с UTF-16. И как вы собираетесь отличать другие неоднозначные диапазоны? Например, 6f 6f означает «oo» или «潯»?
  • 0
    @Jon: Визуально, так же, как пользователи делают это с представлением ASCII в существующих двоичных редакторах / средствах просмотра . Пользователь должен будет выбрать кодировку для правой панели.
Показать ещё 3 комментария
Теги:
unicode
utf-8

1 ответ

1

Как насчет декодирования одного символа за раз, чтобы вы могли захватить количество байтов, которое занимает каждый символ. Что-то вроде этого:

string data  = "hello????";

byte[] buffer = new byte[Encoding.UTF8.GetByteCount(data)];
int bufferIndex = 0;

for(int i = 0; i < data.Length; i++)
{
    int bytes = Encoding.UTF8.GetBytes(data, i, 1, buffer, bufferIndex);

    Console.WriteLine("Character: {0}, Position: {1}, Bytes: {2}", data[i], i, bytes);

    bufferIndex += bytes;
}

Fiddle: https://dotnetfiddle.net/poohHM

Те, которые? "В строке, должны быть многобайтными символами, но SO dosent позволяют мне вставлять их. См. Fiddle.

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

  • 0
    О, это лучше, по крайней мере, для реальных текстовых данных. Форматы UTF являются самосинхронизирующимися, поэтому они прекрасно справляются с двоичными данными. Проблема, которую я вижу, заключается в том, что при сбое декодирования многобайтового символа определение того, какой байт был плохим (и что означали «предыдущие» байты), потребует дополнительной работы.
  • 0
    Я имею в виду, идея лучше. Ваш ответ и скрипка кодируют, а не декодируют.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню