Действительно Хорошие, Плохие [закрытые] данные тестирования в качестве примера UTF-8

В C# Вы, возможно, использовали System.Reflection, хотя в Java я не знаю. Хотя я чувствую желание ответить на это так или иначе с тех пор, если Вы "чувствуете, что Вы нуждаться к закрытым методам модульного теста" в моем предположении - то, что существует что-то еще, что является неправильным...

я серьезно рассмотрел бы рассмотрение моей архитектуры снова новыми глазами...

82
задан Jonathan Leffler 6 January 2014 в 04:22
поделиться

4 ответа

93
ответ дан 24 November 2019 в 09:15
поделиться

Wikipedia’s UTF-8 article has a good summary of what byte sequences are valid/invalid. Another article that’s worth reading is W3C I18N FAQ: Multilingual Forms.

5
ответ дан 24 November 2019 в 09:15
поделиться

У меня были неверные данные теста, что вызвало у меня некоторое замешательство. На основе Как избежать спотыкания о спецификации UTF-8 при чтении файлов Я обнаружил, что это сработало:

private readonly string _byteOrderMarkUtf8 =
    Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble());

public string GetXmlResponse(Uri resource)
{
    string xml;

    using (var client = new WebClient())
    {
        client.Encoding = Encoding.UTF8;
        xml = client.DownloadString(resource);
    }

    if (xml.StartsWith(_byteOrderMarkUtf8, StringComparison.Ordinal))
    {
        xml = xml.Remove(0, _byteOrderMarkUtf8.Length);
    }

    return xml;
}

Правильная установка клиентского свойства Encoding сокращает спецификацию до одного символа. Однако XDocument.Parse по-прежнему не будет читать эту строку. Это самая чистая версия, которую я когда-либо придумал.

байты 0xF5..0xFF не могут встречаться.

Неминимальные последовательности

Для некоторых символов существует несколько возможных представлений. Например, символ Unicode U + 0000 (ASCII NUL) может быть представлен следующим образом:

0x00
0xC0 0x80
0xE0 0x80 0x80
0xF0 0x80 0x80 0x80

Однако стандарт Unicode четко заявляет, что последние три альтернативы неприемлемы, поскольку они не являются минимальными. Так получилось, что байты 0xC0 и 0xC1 никогда не могут появиться в допустимом UTF-8, потому что единственные символы, которые могут быть закодированы ими, минимально закодированы как однобайтовые символы в диапазоне 0x00..0x7F.

Суррогаты UTF-16

В базовой многоязычной плоскости (BMP) значения Unicode U + D800 - U + DFFF зарезервированы для суррогатов UTF-16 и не могут отображаться в кодировке действительного UTF-8. Если бы они были действительны в UTF-8 (что, я подчеркиваю, не является), то суррогаты были бы закодированы:

  • U + D800 - 0xED 0xA0 0x80 (наименьший старший суррогат)
  • U + DBFF - 0xED 0xAF 0xBF (наибольший старший суррогат)
  • U + DC00 - 0xED 0xB0 0x80 (наименьший младший суррогат)
  • U + DFFF - 0xED 0xBF 0xBF (самый большой младший суррогат)

Плохие данные

Итак, ваши данные BAD должны содержать образцы, нарушающие эти различные предписания.

  • Байт продолжения, которому не предшествует одно из начальных значений байта
  • Многократно. начальные байты символа, за которыми не следует достаточное количество байтов продолжения
  • Неминимальные многобайтовые символы
  • Суррогаты UTF-16
  • Недействительные байты (0xC0, 0xC1, 0xF5..0xFF).

Обратите внимание, что байт- Метка порядка (BOM) U + FEFF, также известная как неразрывный пробел нулевой ширины (ZWNBSP), не может отображаться незакодированной в UTF-8 - байты 0xFF и 0xFE не допускаются в допустимом UTF-8. Закодированный ZWNBSP может отображаться в файле UTF-8 как 0xEF 0xBB 0xBF, но спецификация полностью излишняя в UTF-8.


Есть также некоторые несимволы в Unicode. U + FFFE и U + FFFF - два таких несимвола (и последние две кодовые точки в каждой плоскости, U + 1FFFE, U + 1FFFF, U + 2FFFE, U + 2FFFF, ... U + 10FFFE, U + 10FFFF - другие ). Обычно они не должны появляться в данных Unicode для обмена данными, но могут появляться при частном использовании. См. Ссылку на часто задаваемые вопросы по Unicode для получения множества грязных подробностей, включая довольно сложную историю несимволов в Unicode. ( Исправление № 9: Разъяснение относительно несимволов , выпущенное в январе 2013 года, делает то, что предполагает его название - разъясняет значение несимволов.)

U + 1FFFF, U + 2FFFE, U + 2FFFF, ... U + 10FFFE, U + 10FFFF и другие). Обычно они не должны появляться в данных Unicode для обмена данными, но могут появляться при частном использовании. См. Ссылку на часто задаваемые вопросы по Unicode для получения множества грязных подробностей, включая довольно сложную историю несимволов в Unicode. ( Исправление № 9: Разъяснение относительно несимволов , выпущенное в январе 2013 года, делает то, что предполагает его название - разъясняет значение несимволов.)

U + 1FFFF, U + 2FFFE, U + 2FFFF, ... U + 10FFFE, U + 10FFFF и другие). Обычно они не должны появляться в данных Unicode для обмена данными, но могут появляться при частном использовании. См. Ссылку на часто задаваемые вопросы по Unicode для получения множества грязных подробностей, включая довольно сложную историю несимволов в Unicode. ( Исправление № 9: Разъяснение относительно несимволов , выпущенное в январе 2013 года, делает то, что предполагает его название - разъясняет значение несимволов.)

34
ответ дан 24 November 2019 в 09:15
поделиться

Внезапно:

0xff и 0xfe

Отдельные байты старшего разряда

Многобайтовые представление младших байтовых символов - Хороший способ перебросить нули после ранних проверок

Метки порядка байтов - Вы собираетесь игнорировать их?

NFC vs. NFD

2
ответ дан 24 November 2019 в 09:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: