protobuf - это двоичный протокол (если вы не говорите о необязательном json).Итак, каждый раз, когда вы воспринимаете его как текстовый , любым способом , вы используете его неправильно и поведение будет неопределенным.Это включает беспокойство о том, существуют ли символы CR / LF, но также включает такие вещи, как нуль-символ (0x00), который часто интерпретируется как конец строки в текстовых API во многих средах (в частности, в C-строки).
В частности:
- LF (0x0A) идентичен заголовку поля для «поля 1 с префиксом длины»
- CR (0x0D):идентичен заголовку поля для «поля 1, фиксированный 32-разрядный»
- любой из 0x00, 0x0A или 0x0D может встречаться в качестве префикса длины (для обозначения длины 0, 10 или 13)
- любой из 0x00, 0x0A или 0x0D может встречаться естественным образом в двоичных данных (
bytes
) - любой из 0x00, 0x0A или 0x0D может встречаться естественным образом в любом числовом типе
- 0x0A или 0x0Dможет происходить естественным образом в текстовых данных (как 0x00, если ваша исходная структура допускает nul-символов произвольно в строках, так что ... не в C-строках)
- и, возможно, в ряде других вещей
Итак: еще раз - если включить «специальные»текстовые символы проблематичны: вы используете его неправильно .
Наиболее распространенный способ обработки двоичных данных в виде текста - это использование кодировки base-N;base-16 (hex) удобен для отображения и чтения, но base-64 более эффективен с точки зрения количества символов, необходимых для передачи одинакового количества байтов.Поэтому, если возможно: конвертируйте в / из base-64 по мере необходимости.Base-64 никогда не содержит никаких непечатных символов, поэтому вы никогда не встретите CR / LF / nul.