UTF-8 - это относительно простой способ кодирования кодовых точек Unicode в формате переменной ширины, так что он не может легко перепутать код, не поддерживающий Unicode.
Обзор UTF-8
- Байты в диапазоне 1-0x7F включительно, как правило, действительны
- Байты с битовой комбинацией
10XX XXXX
считаются байтами продолжения, причем шесть наименее значимых битов используются для кодирования части кодовой точки. Они не должны появляться, если они не ожидаются предшествующим байтом. - Байты с шаблоном
110X XXXX
ожидают один байт продолжения после - Байты с шаблоном
1110 XXXX
ожидают два байта продолжения после - Байты с шаблоном
1111 0XXX
ожидают три продолжения байта после - Все остальные байты недопустимы и не должны появляться где-либо в потоке UTF-8. 5, 6 и 7-байтовые кластеры теоретически возможны, но не будут допущены для этой задачи.
Сверхдлинные кодировки
UTF-8 также требует, чтобы кодовая точка была представлена минимальным количеством байтов. Любая последовательность байтов, которая может быть представлена меньшим количеством байтов, недопустима. Модифицированный UTF-8 добавляет к этому исключение для нулевых символов (U + 0000), который должен быть представлен как C0 80
(шестнадцатеричное представление), и вместо этого запрещает появление нулевых байтов в любом месте потока. (Это делает его совместимым со строками с нулевым символом в конце)
Вызов
Вы должны создать программу, которая при задании строки байтов будет определять, представляет ли эта строка действительный Модифицированный UTF-8, и будет возвращать истинное значение, если оно действительно, и ложное значение в противном случае. Обратите внимание, что вы должны проверить наличие слишком длинных кодировок и нулевых байтов (так как это модифицированный UTF-8). Вам не нужно декодировать значения UTF-8.
Примеры
41 42 43 ==> yes (all bytes are in the 0-0x7F range)
00 01 02 ==> no (there is a null byte in the stream)
80 7F 41 ==> no (there is a continuation byte without a starter byte)
D9 84 10 ==> yes (the correct number of continuation bytes follow a starter byte)
F0 81 82 41 ==> no (there are not enough continuation bytes after F0)
EF 8A A7 91 ==> no (too many continuation bytes)
E1 E1 01 ==> no (starter byte where a continuation byte is expected)
E0 80 87 ==> no (overlong encoding)
41 C0 80 ==> yes (null byte encoded with the only legal overlong encoding)
F8 42 43 ==> no (invalid byte 'F8')
правила
- Применяются стандартные правила и лазейки
- Вход и выход могут быть в любом удобном формате, если все значения в диапазоне байтов без знака (0-255) могут быть считаны.
- Возможно, вам придется использовать массив или файл, а не строку с нулевым символом в конце. Вы должны уметь читать нулевые байты.
- Самый короткий код выигрывает!
- Обратите внимание, что использование встроенных функций для декодирования UTF-8 не гарантирует соответствие приведенным здесь требованиям. Возможно, вам придется обойти это и создать особые случаи.
РЕДАКТИРОВАТЬ: добавлен бонус за неиспользование встроенных в декодер UTF-8
EDIT2: удален бонус, так как квалифицирован только ответ на Rust, и его неудобно определять.