Может ли UTF-8 содержать нулевой байт?

Может ли строка UTF-8 содержать zerobytes? Я собираюсь отправить его по протоколу ascii plaintext, должен ли я закодировать его с чем-то вроде base64?

Ответ 1

Да, нулевой байт в UTF8 - это кодовая точка 0, NUL. Нет другой кодовой точки Unicode, которая будет закодирована в UTF8 с нулевым байтом в любом месте.

Возможные кодовые точки и их кодировка UTF8:

Range              Encoding  Binary value
-----------------  --------  --------------------------
U+000000-U+00007f  0xxxxxxx  0xxxxxxx

U+000080-U+0007ff  110yyyxx  00000yyy xxxxxxxx
                   10xxxxxx

U+000800-U+00ffff  1110yyyy  yyyyyyyy xxxxxxxx
                   10yyyyxx
                   10xxxxxx

U+010000-U+10ffff  11110zzz  000zzzzz yyyyyyyy xxxxxxxx
                   10zzyyyy
                   10yyyyxx
                   10xxxxxx

Вы можете видеть, что все ненулевые символы ASCII представлены как сами, в то время как все последовательности mutibyte имеют высокий бит из 1 во всех своих байтах.

Возможно, вам нужно быть осторожным, чтобы ваш протокол ascii plaintext не обрабатывал символы, отличные от ASCII, плохо (так как это будут все точки кода, отличные от ASCII).

Ответ 2

Закодированная строка UTF-8 может иметь большинство значений от 0x00 до 0xff в заданной позиции байта для резервной памяти (хотя некоторые конкретные комбинации не разрешены, см. http://en.wikipedia.org/wiki/UTF-8, а октетные значения C0, C1, F5-FF никогда не появляются).

Если вы перемещаетесь по каналу, например потоку ASCII, который не поддерживает двоичные данные, вам необходимо соответствующим образом закодировать. Base64 широко поддерживается и, безусловно, решит эту проблему, хотя он не является полностью эффективным, поскольку он использует пространство с 64 символами для кодирования данных, тогда как ASCII позволяет использовать пространство с 128 символами.

Существует проект sourceforge, который обеспечивает базовую кодировку 91, которая является более эффективной с точки зрения пространства, избегая при этом непечатаемых символов http://base91.sourceforge.net/

Ответ 3

Текст ASCII ограничен байтовыми значениями между 0 и 127. Текст UTF-8 не имеет такого ограничения - текст, закодированный с UTF-8, может иметь свой высокий бит. Поэтому небезопасно отправлять текст UTF-8 по каналу, который не гарантирует безопасный проход для этого высокого бита.

Если вы вынуждены иметь дело с ASCII-каналом, Base-64 является разумным (хотя и не особенно экономичным). Вы уверены, что ограничены 7-битными данными? Это несколько необычно в этот день.