Разграничение двоичных последовательностей - PullRequest
13 голосов
/ 17 декабря 2011

Мне нужно иметь возможность разграничить поток двоичных данных.Я думал об использовании чего-то вроде символа ASCII EOT (Конец передачи), чтобы сделать это.

Однако я немного обеспокоен - как я могу точно знать, что конкретная двоичная последовательность используется для этого (0b00000100) не появится в моих собственных двоичных последовательностях, что дает ложный положительный результат при разделении?

Другими словами, как лучше всего обрабатывать двоичное разделение?

РЕДАКТИРОВАТЬ: ... без использованиядлина заголовка.Извините, ребята, я должен был упомянуть об этом раньше.

Ответы [ 5 ]

12 голосов
/ 17 декабря 2011

У вас есть пять вариантов:

  • Используйте символ разделителя, который вряд ли произойдет.Это рискует вас угадать неправильно.Я не рекомендую такой подход.
  • Используйте символ разделителя и escape-последовательность , чтобы включить разделитель.Возможно, вам придется удвоить escape-символ, в зависимости от того, что облегчает анализ.(Представьте, что C \0 включает NUL ASCII в некоторый контент.)
  • Используйте разделитель фразу , который, как вы можете определить, не встречается.(Подумайте о границах сообщений mime .)
  • Добавьте какое-либо поле length , чтобы вы знали, что следующие N байтов в качестве данных.Недостатком является то, что вы должны знать эту длину до записи данных, что иногда трудно или невозможно.
  • Используйте что-то гораздо более сложное, например ASN.1 , чтобы полностью описать все ваш контент для вас.(Я не знаю, рекомендую ли я это на самом деле, если только вы не сможете хорошо использовать его - ASN.1 неудобно использовать в лучших обстоятельствах, но допускает совершенно однозначные двоичные данныеинтерпретация.)
8 голосов
/ 17 декабря 2011

Обычно вы упаковываете свои двоичные данные в хорошо известный формат, например, с фиксированным заголовком, который описывает последующие данные. Если вы пытаетесь найти разделители в неизвестном потоке данных, обычно вам нужна escape-последовательность. Например, что-то вроде HDLC, где 0x7E - разделитель кадров. Данные должны быть закодированы таким образом, чтобы при наличии 0x7E внутри данных они заменялись на 0x7D, за которым следует XOR исходных данных. 0x7D в потоке данных аналогично экранируется.

3 голосов
/ 17 декабря 2011

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

3 голосов
/ 17 декабря 2011

Если двоичные записи действительно могут содержать какие-либо данные, попробуйте добавить длину перед данными вместо маркера после данных. Это иногда называют длиной префикса, потому что длина предшествует данным.

В противном случае вам придется экранировать разделитель в потоке байтов (и экранировать escape-последовательность).

0 голосов
/ 04 июня 2019

В качестве альтернативы с ограниченным пространством и фиксированными накладными расходами для добавления данных к полям размера и экранирования символа-разделителя можно использовать кодировку escapeless , чтобы обрезать этот символ-разделитель, возможно, вместе с другими символами это должно иметь особое значение, исходя из ваших данных.

...