Hello,
Recently I was faced with the task of escaping multiple chars in a frame payload, and it has to be done with minimal worst-case overhead on a microcontroller. That rules out classic escape chars since it has a worst-case overhead of 100%.
I was looking at
https://en.wikipedia.org/wiki/Consistent_Overhead_Byte_Stuffing, which escapes only one char, then came up with the realization that if one limits its block length to less than 254, the overhead byte is likewise limited in range, and the unused bits can be used for recovering the original char. I searched the web but couldn't find anything, so I decided to post it here, in case anyone finds it useful:
1. Suppose we need to escape 3 bits (
0x00-0x07)
2. To encode a string, first append a
0x00, then break it into blocks of either (a) 30 non-escape chars, or (b) 0-29 non escape chars + 1 escape char. For (a), prepend the block with
0xF8; for (b), move the escape char to the beginning of block, and set its high 5 bit to the block length (1-30).
3. To decode a string, read it sequentially. If the current char is
0xF8, drop it and output the next 30 chars. If the current char is less than
0xF8, let the low 3 bit of the current char be the non-escaped char, the high 5 bit be the block length; output the next (block length - 1) chars, then append the non-escaped char. At the end, remove the prepended
0x00.
4. Obviously you could modify how many bits are used. If you need to escape other specific chars, simply exchange them with
0x00-0x07 after encode, and exchange again before decode.
I call it the
PolyCOBS algorithm, since it's a strict extension of the original COBS (if you set number of bits to zero, it's exactly equivalent to the original COBS).
In the case above (3 bits), the worst-case overhead is ~3%. The smaller block length also helps decoding on microcontrollers, making
https://github.com/Dirbaio/rcobs almost unnecessary, but if you are really limited in RAM, you can even combine that.