Я здивований, що цього раніше не публікували!
Алгоритм послідовного набивання накладних байтів (COBS) використовується для розмежування потоків байтів.
Ми вибираємо маркер кадру (ми будемо використовувати 0x00) і там, де в потоці трапляється 0x00, він замінюється кількістю байтів, поки не відбудеться наступний 0x00 (це назвемо етапом). Це зменшує діапазон значень від 0..255 до 1..255, що дозволяє 0x00 однозначно розмежовувати кадри в потоці.
На етапі, якщо наступні 255B не містять 0x00, це перевищує максимальну довжину етапу - алгоритм повинен "затриматись" на рівні 255B і поставити ще одну віху. Це "послідовний накладні витрати".
Перший байт буде першою віхою, остаточним етапом буде кількість байтів до маркера кадру.
Деякі приклади з Вікіпедії (найкраще прочитати статтю, де вони кольорові):
0x00 as frame marker
Unencoded data (hex) Encoded with COBS (hex)
00 01 01 00
00 00 01 01 01 00
11 22 00 33 03 11 22 02 33 00
11 22 33 44 05 11 22 33 44 00
11 00 00 00 02 11 01 01 01 00
01 02 03 ... FD FE FF 01 02 03 ... FD FE 00
00 01 02 ... FC FD FE 01 FF 01 02 ... FC FD FE 00
01 02 03 ... FD FE FF FF 01 02 03 ... FD FE 02 FF 00
02 03 04 ... FE FF 00 FF 02 03 04 ... FE FF 01 01 00
03 04 05 ... FF 00 01 FE 03 04 05 ... FF 02 01 00
Завдання: реалізувати це в найкоротшій програмі.
- Вхід - це некодований байт-потік / масив, вихід - кодований байт-потік / масив
- Використовуйте будь-який тип двійкового стандартного вводу / виводу
- Кінцевий маркер кадру не потрібен
- Програма може повернути негабаритний масив
- Потік, що закінчується 254 ненульовими байтами, не вимагає завершення 0x00
Примітки
- Найгірша довжина повернення - це
numBytes + (numBytes / 254) + 1
Приклад
У нас є масив байтів
[0] 0x01
[1] 0x02
[2] 0x00
[3] 0x03
[4] 0x04
[5] 0x05
[6] 0x00
[7] 0x06
Для кожного 0x00
нам потрібно зазначити (на етапі), де було 0x00
б наступне .
[0] 0x03 #Milestone. Refers to the original [2] - "The next 0x00 is in 3B"
[1] 0x01 #Original [0]
[2] 0x02 #Original [1]
[3] 0x04 #Milestone. Refers to the original [6] - "The next 0x00 is in 4B"
[4] 0x03 #
[5] 0x04 #
[6] 0x05 # Originals [3..5]
[7] 0x02 #Milestone. Refers to the end frame marker
[8] 0x06 #Original [7]
[9] 0x00 #Optional. End frame marker.
01
але 01
в дев’ятому є два s (де 254 ненульових байти, а за ними нуль).