Перейти к содержанию

Байт-стаффинг (byte stuffing)

Если конец кадра отмечают особым байтом, этот байт может случайно оказаться и в самих данных. Байт-стаффинг — общее название приёмов, которые перекодируют данные так, чтобы служебный байт в них больше не встречался, а приёмник мог однозначно восстановить исходное.

Обновлено Редакция GAW

Байт-стаффинг (byte stuffing) — перекодирование данных перед передачей так, чтобы в них не встречались зарезервированные значения байтов, прежде всего разделитель кадра. Приёмник выполняет обратное преобразование и получает исходные данные. Cheshire и Baker определяют его через накладные расходы: на выходе получается последовательность, возможно, длиннее исходной, и разница в длине — плата за прозрачность.

Два подхода

Экранирующий символ. Выбирают два служебных байта: разделитель и признак экранирования. Совпавший с любым из них байт данных передают парой «экран + замена». Так работает SLIP: 0xC0 в данных превращается в DB DC, 0xDB — в DB DD; в исходном коде RFC 1055 символ ESC прямо подписан как признак байт-стаффинга. Просто и потоково, но размер кадра зависит от содержимого: худший случай — удвоение.

Переписывание блоками. COBS вообще убирает из данных нули: вместо экранирования каждого совпадения он хранит перед каждым блоком расстояние до следующего нуля. Худший случай — один лишний байт на 254.

АлгоритмРазделительХудший рост кадра
SLIP (RFC 1055)0xC0вдвое
COBS0x001 байт на 254

Отличие от битстаффинга

Битстаффинг делает то же самое на уровне битов: HDLC вставляет ноль после пяти единиц подряд, чтобы флаг 01111110 не появился внутри данных. Он встроен в аппаратуру контроллеров CAN, USB и HDLC. Байт-стаффинг выполняет программа, потому что UART передаёт байты как есть и ничего о кадрах не знает.

Где нужен

Когда протокол поверх последовательного канала отмечает границы кадров особым байтом, а не паузами или полем длины. Способы кадрирования и их сравнение с примерами кода — в статье о реализации протоколов.

Частые вопросы

Чем байт-стаффинг отличается от битстаффинга?

Единицей обработки. Битстаффинг работает с отдельными битами: HDLC вставляет ноль после пяти единиц подряд, CAN — бит противоположного уровня после пяти одинаковых, USB — ноль после шести единиц подряд перед кодированием NRZI. Байт-стаффинг работает с целыми байтами и нужен там, где линия передаёт байты, как UART: заменяет байты, совпавшие с разделителем.

Насколько байт-стаффинг увеличивает кадр?

Зависит от данных и алгоритма. В схеме с экранирующим символом (SLIP) каждый совпавший байт превращается в два, и в худшем случае кадр удваивается — Cheshire и Baker называют этот худший случай 200 %. COBS гарантирует не больше одного лишнего байта на 254.

Нужен ли байт-стаффинг, если кадры разделяются паузой?

Нет. Modbus RTU отделяет кадры тишиной длиной 3,5 символа, а общей длины кадра не передаёт (у части функций есть только поле Byte Count — число байтов данных), и данные могут содержать любые байты. Байт-стаффинг нужен, когда граница кадра обозначена байтом, а паузы на линии ненадёжны, например при передаче через USB CDC или буферизующие преобразователи.

Источники

  1. S. Cheshire, M. Baker. Consistent Overhead Byte Stuffing. IEEE/ACM Transactions on Networking, vol. 7, no. 2, April 1999 — аннотация и разд. I: байт-стаффинг кодирует последовательность байтов, которая может содержать любые значения, в потенциально более длинную последовательность без зарезервированных значений; разница в длине — накладные расходы; у алгоритмов SLIP, PPP и AX.25 малые средние расходы, но худший случай — 200 %; COBS ограничивает худший случай одним байтом на 254; разд. II: битстаффинг HDLC вставляет ноль после пяти единиц подряд
  2. J. Romkey. RFC 1055: A Nonstandard for Transmission of IP Datagrams over Serial Lines: SLIP, June 1988 — в исходном коде символ ESC прямо назван «indicates byte stuffing»; END (0xC0) в данных заменяется парой ESC ESC_END, ESC (0xDB) — парой ESC ESC_ESC

Нашли ошибку?