Dziwię się, że nie zostało to wcześniej opublikowane!
Zgodnie bajtu narzutu Napełniacz (COB) algorytm jest stosowany do strumieni ograniczają bajtów.
Wybieramy znacznik ramki (użyjemy 0x00) i wszędzie tam, gdzie w strumieniu występuje 0x00, jest on zastępowany liczbą bajtów aż do następnego 0x00 (nazywamy to kamieniem milowym). Zmniejsza to zakres wartości od 0..255 do 1..255, umożliwiając 0x00 jednoznaczne wyznaczanie ramek w strumieniu.
W przypadku kamienia milowego, jeśli następne 255B nie będzie zawierało 0x00, przekroczy to maksymalną długość kamienia milowego - algorytm musi zatrzymać się na 255B i umieścić kolejny kamień milowy. Jest to „konsekwentny koszt ogólny”.
Pierwszy bajt będzie pierwszym kamieniem milowym, ostatnim kamieniem milowym będzie liczba bajtów do znacznika ramki.
Kilka przykładów z Wikipedii (najlepiej przeczytać artykuł, w którym są kolorowe):
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
Wyzwanie: wdrożyć to w najkrótszym programie.
- Wejście to niekodowany strumień bajtów / tablica, wyjście to zakodowany strumień bajtów / tablica
- Użyj dowolnego binarnego standardowego wejścia / wyjścia
- Znacznik ostatniej klatki nie jest konieczny
- Program może zwrócić ponadwymiarową tablicę
- Strumień kończący się na 254 niezerowych bajtów nie wymaga końcowego 0x00
Notatki
- Najgorsza długość zwrotu to
numBytes + (numBytes / 254) + 1
Przykład
Mamy tablicę bajtów
[0] 0x01
[1] 0x02
[2] 0x00
[3] 0x03
[4] 0x04
[5] 0x05
[6] 0x00
[7] 0x06
Dla każdego z nich 0x00
musimy określić (w kamieniu milowym), gdzie 0x00
byłby następny .
[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
ale 01
w dziewiątym są dwa s (gdzie jest 254 bajtów niezerowych, po których następuje zero).