COBS (Overhead Overhead Consistente)


10

Estou surpreso que isso não tenha sido publicado antes!

O algoritmo COBS ( Overhead Byte Overhead Consistente ) é usado para delimitar fluxos de bytes.

Escolhemos um marcador de quadro (usaremos 0x00) e, sempre que 0x00 ocorre no fluxo, ele é substituído pelo número de bytes até o próximo 0x00 (chamaremos isso de marco). Isso reduz o intervalo de valores de 0..255 a 1..255, permitindo que 0x00 delimite inequivocamente os quadros no fluxo.
Em um marco, se o próximo 255B não contiver 0x00, isso excede o comprimento máximo do marco - o algoritmo deve 'parar' em 255B e colocar outro marco. Essa é a "sobrecarga consistente".
O primeiro byte será o primeiro marco, o marco final será o número de bytes até o marcador do quadro.

Alguns exemplos da Wikipedia (melhor ler o artigo em que são coloridos):

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

Desafio: implementar isso no programa mais curto.

  • A entrada é um fluxo / matriz de bytes não codificados, a saída é um fluxo / matriz de bytes codificados
  • Use qualquer tipo de entrada / saída padrão binária
  • O marcador de quadro final não é necessário
  • O programa pode retornar uma matriz de grandes dimensões
  • Um fluxo que termina com 254 bytes diferentes de zero não requer o 0x00 à direita

Notas

  • O pior retorno do comprimento é numBytes + (numBytes / 254) + 1

Exemplo

Temos a matriz de bytes

[0] 0x01
[1] 0x02
[2] 0x00
[3] 0x03
[4] 0x04
[5] 0x05
[6] 0x00
[7] 0x06

Para cada um 0x00, precisamos declarar (em um marco) onde o próximo 0x00teria sido.

[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.

3
Você provavelmente deve incluir isso na especificação: Como uma exceção especial, se um pacote terminar com um grupo de 254 bytes diferentes de zero, não será necessário adicionar o byte zero à direita. Isso economiza um byte em algumas situações. (citando Wikipedia)
Arnauld

3
@LuisMendo Concordou. Agora que já percorri todos os casos de teste, posso confirmar que isso está atualmente um pouco subespecificado.
Arnauld

@Arnauld, já disse a fabricante de quadro final não é de qualquer maneira necessária :)
Patrick

No exemplo, o primeiro byte de saída deve ser 0x03, 0x02 não, se não me engano ...
Olivier Grégoire

11
@Arnauld referente a um caso especial de finalização com 254 bytes diferentes de zero: concordo, e esse é um problema separado para o marcador de quadro final. É por isso que o sexto exemplo não tem um final, 01mas há dois 01s no nono (onde existem 254 bytes diferentes de zero seguidos de um zero).
Nick Kennedy

Respostas:





1

Gelatina , 27 bytes

Oµ=0ks€254Ẏḟ€0L‘;Ɗ€F;Ṫ¬x`ƊỌ

Experimente online!

Um link monádico que recebe uma matriz de bytes não codificados como entrada e retorna a matriz de bytes codificados. De acordo com as regras, o marcador de quadro final é omitido.

Explicação

Oµ                          | Convert to integer and start a new monadic chain
  =0k                       | Split after zeros
     s€254                  | Split each list into length 254 lists
          Ẏ                 | Tighten (reduce list depth by 1)
           ḟ€0              | Filter zeros out from each list
              L‘;Ɗ€         | Prepend the list length plus one to each list
                   F        | Flatten
                    ;Ṫ¬x`Ɗ  | Append an additional 1 if the original list ended with zero
                          Ọ | Convert back to bytes


0

J , 103 caracteres

Observe que o resultado do último caso de teste é diferente do wiki e de outros idiomas. Isso ocorre devido a esse ponteiro para 254-th byte zero no limite. As coisas ficam muito mais fáceis, se isso não for tratado como um caso especial.

f =: 3 : 0
  k =. I. (y,0)=0
  s =. - 2 (-/) \ k
  (>: y i. 0), s (}:k) } y
 )

 f2 =: 3 : 0
   f each _254 <\ y
 )

Experimente Online


Você pode reduzir 1 byte removendo o espaço à direita no final da última linha.
precisa saber é o seguinte
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.