Может ли строка UTF-8 содержать zerobytes? Я собираюсь отправить его по протоколу ascii plaintext, должен ли я закодировать его с чем-то вроде base64?
Может ли UTF-8 содержать нулевой байт?
Ответ 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-битными данными? Это несколько необычно в этот день.