См. Также Как файлу с китайскими символами известно, сколько байтов использовать на символ? - без сомнения, есть и другие SO-вопросы, которые также могут помочь.
В UTF-8 вы получаете следующие типы байтов:
Binary Hex Comments
0xxxxxxx 0x00..0x7F Only byte of a 1-byte character encoding
10xxxxxx 0x80..0xBF Continuation bytes (1-3 continuation bytes)
110xxxxx 0xC0..0xDF First byte of a 2-byte character encoding
1110xxxx 0xE0..0xEF First byte of a 3-byte character encoding
11110xxx 0xF0..0xF4 First byte of a 4-byte character encoding
(Последняя строка выглядит так, как будто она должна читать 0xF0..0xF7; однако 21-битный диапазон Unicode (U + 0000 - U + 10FFFF) означает, что максимальное допустимое значение - 0xF4; значения 0xF5..0xF7 не могут встречаться в действительный UTF-8.)
Проверка того, является ли конкретная последовательность байтов допустимой для UTF-8, означает, что вам нужно подумать о:
- Байты продолжения появляются там, где не ожидалось
- Появление байтов, не являющихся продолжением, там, где ожидается байт продолжения
- Неполные символы в конце строки (вариант «ожидаемого байта продолжения»)
- Неминимальные последовательности
- Суррогаты UTF-16
В допустимом UTF-8 байты 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, но BOM полностью излишни в UTF-8.
В Юникоде также есть некоторые несимволы . U + FFFE и U + FFFF - два таких несимвола (и последние две кодовые точки в каждой плоскости, U + 1FFFE, U + 1FFFF, U + 2FFFE, U + 2FFFF, ... U + 10FFFE, U + 10FFFF - другие ). Обычно они не должны появляться в данных Unicode для обмена данными, но могут появляться при частном использовании. См. Ссылку на часто задаваемые вопросы по Unicode для получения множества грязных подробностей, включая довольно сложную историю несимволов в Unicode. ( Исправление № 9: Разъяснение о несимволах , выпущенное в январе 2013 года, делает то, что предполагает его название - разъясняет значение несимволов .)