a zero data byte that was altered by encoding. All zero data bytes are replaced during encoding by the offset to the following zero byte (i.e. one plus the number of non-zero bytes that follow). It is effectively a pointer to the next packet byte that requires interpretation: if the addressed byte is non-zero then it is the following that points to the next byte requiring interpretation; if the addressed byte is zero then it is the . is an overhead byte which is also a group header byte containing an offset to a following group, but does not correspond to a data byte. These appear in two places: at the beginning of every encoded packet, and after every group of 254 non-zero bytes. A zero byte appears at the end of every packet to indicate end-of-packet to the data receiver. This packet delimiter byte is not part of COBS proper; it is an additional framing byte that is appended to the encoded output. Below is a diagram using example 4 from above table, to illustrate how each modified data byte is located, and how it is identified as a data byte or an end of frame byte. [OHB] : Overhead byte (Start of frame) 3+ -------------->| : Points to relative location of first zero symbol 2+-------->| : Is a zero data byte, pointing to next zero symbol [EOP] : Location of end-of-packet zero symbol. 0 1 2 3 4 5 : Byte Position 03 11 22 02 33 00 : COBS Data Frame 11 22 00 33 : Extracted Data OHB = Overhead Byte (Points to next zero symbol) EOP = End Of Packet Examples 7 through 10 show how the overhead varies depending on the data being encoded for packet lengths of 255 or more. Implementation The following code implements a COBS encoder and decoder in the C programming language: #include <stddef.h> #include <stdint.h> #include <assert.h> /** COBS encode data to buffer @param data Pointer to input data to encode @param length Number of bytes to encode @param buffer Pointer to encoded output buffer @return Encoded buffer length in bytes @note Does not output delimiter byte */ size_t cobsEncode(const void *data, size_t length, uint8_t *buffer) { assert(data && buffer); uint8_t *encode = buffer; // Encoded byte pointer uint8_t *codep = encode++; // Output code pointer uint8_t code = 1; // Code value for (const uint8_t *byte = (const