Разграничение двоичных последовательностей
Мне нужно иметь возможность разграничить поток двоичных данных. Я думал об использовании чего-то вроде символа ASCII EOT (End of Transmission) для этого.
Однако я немного обеспокоен - как я могу точно знать, что конкретная двоичная последовательность, используемая для этого (0b00000100), не будет отображаться в моих собственных двоичных последовательностях, что дает ложное положительное значение для делимитации?
Другими словами, как наилучшим образом обрабатывается двоичное разграничение?
EDIT:... Без использования заголовка длины. Извините, ребята, должен был упомянуть об этом раньше.
Ответы
Ответ 1
Обычно вы переносите свои двоичные данные в хорошо известный формат, например, с фиксированным заголовком, который описывает последующие данные. Если вы пытаетесь найти разделители в неизвестном потоке данных, обычно вам нужна escape-последовательность. Например, что-то вроде HDLC, где 0x7E - это рамочный делитель. Данные должны быть закодированы таким образом, что если в данных есть 0x7E, он заменяется 0x7D, за которым следует XOR исходных данных. 0x7D в потоке данных аналогично экранируется.
Ответ 2
У вас есть пять вариантов:
- Используйте символ разделителя, который вряд ли произойдет. Это рискует неправильно догадаться. Я не рекомендую этот подход.
- Используйте разделительный символ и escape-последовательность, чтобы включить разделитель. Вам может потребоваться удвоить escape-символ, в зависимости от того, что упрощает парсинг. (Подумайте, C
\0
включить ASCII NUL в некоторый контент.)
- Использовать фразу-разделитель, которую вы можете определить, не возникает. (Подумайте о границах сообщений .)
- Подготовьте какое-то поле длины, поэтому вы знаете, как читать следующие N байтов в качестве данных. Это имеет недостаток, требуя от вас знать эту длину, прежде чем писать данные, что иногда сложно или невозможно.
- Используйте что-то гораздо более сложное, например ASN.1, чтобы полностью описать весь ваш контент для вас. (Я не знаю, действительно ли я рекомендовал бы это, если вы не сможете его эффективно использовать - ASN.1 неловко использовать в лучших обстоятельствах, но это позволяет полностью однозначную интерпретацию двоичных данных.)
Ответ 3
Если двоичные записи действительно могут содержать какие-либо данные, попробуйте добавить длину перед данными вместо маркера после данных. Это иногда называют длиной префикса, поскольку длина перед данными.
В противном случае вам придется избегать разделителя в потоке байтов (и избежать escape-последовательности).
Ответ 4
Перед этим вы можете добавить размер двоичных данных. Если вы имеете дело с потоковыми данными и не знаете его размер заранее, вы можете разделить его на куски и каждый кусок начать с поля размера.
Если вы установите максимальный размер для куска, вы получите все, кроме последнего фрагмента, ту же длину, что упростит произвольный доступ, если вы этого потребуете.
Ответ 5
В качестве альтернативы с ограниченным пространством и фиксированными накладными расходами для добавления данных к полям размера и экранирования символа-разделителя, безвредное кодирование может использоваться для обрезки этого символа-разделителя, возможно, вместе с другими символами, которые должны иметь особое значение, из ваших данных.,