Tutarlı Tepegöz Bayt Doldurma (COBS)


10

Bunun daha önce gönderilmediğine şaşırdım!

Tutarlı Asma Bayt (COBS) algoritması sınırlandırmaktadır bit akımlar için kullanılır.

Bir kare işaretleyici seçiyoruz (0x00 kullanacağız) ve akışta 0x00 nerede olursa olsun, sonraki 0x00 oluşana kadar bayt sayısı ile değiştirilir (buna bir kilometre taşı diyeceğiz). Bu, değer aralığını 0..255'ten 1..255'e düşürerek 0x00'ün akıştaki kareleri net bir şekilde sınırlamasını sağlar.
Bir kilometre taşında, sonraki 255B 0x00 içermiyorsa bu maksimum kilometre taşı uzunluğunu aşar - algoritma 255B'de 'durmalı' ve başka bir kilometre taşı koymalıdır. Bu 'tutarlı ek yük'.
İlk bayt ilk kilometre taşı, son kilometre taşı ise çerçeve işaretleyiciye kadar bayt sayısı olacaktır.

Wikipedia'dan bazı örnekler (renkli oldukları makaleyi okumak için en iyisi):

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

Zorluk: Bunu en kısa programda uygulamak.

  • Giriş kodlanmamış bir bayt akışı / dizisidir, çıkış kodlanmış bir bayt akışı / dizisidir
  • Herhangi bir ikili standart giriş / çıkış kullanın
  • Son kare işaretçisi gerekli değildir
  • Program büyük boyutlu bir dizi döndürebilir
  • 254 sıfır olmayan bayt ile biten bir akış, son 0x00 gerektirmez

notlar

  • En kötü dönüş uzunluğu numBytes + (numBytes / 254) + 1

Misal

Bayt dizimiz var

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

Her biri 0x00için bir sonraki aşamada nerede 0x00olacağını bir aşamada belirtmeliyiz.

[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
Muhtemelen spesifikasyona dahil etmelisiniz: Özel bir istisna olarak, bir paket sıfır olmayan 254 baytlık bir grupla bitiyorsa, sondaki sıfır baytı eklemek gerekli değildir. Bu, bazı durumlarda bir bayt tasarrufu sağlar. (Wikipedia
alıntısı

3
@LuisMendo Kabul etti. Şimdi tüm test senaryolarını gözden geçirdiğime göre, bunun şu anda biraz eksik olduğunu doğrulayabilirim.
Arnauld

@Arnauld, son çerçeve üreticisinin yine de gerekli olmadığını belirttim :)
Patrick

Örnekte, yanılmadıkça ilk çıkış baytı 0x03 değil, 0x02 olmalıdır ...
Olivier Grégoire

1
@ 254 sıfır olmayan bayt ile biten özel durumla ilgili: kabul edin ve bu son kare işaretçisi için ayrı bir konudur. Bu nedenle altıncı örneğin bir izi yoktur, 01ancak 01dokuzuncu birinde iki s vardır (burada 254 sıfır olmayan bayt ve ardından sıfır vardır).
Nick Kennedy

Yanıtlar:





1

Jöle , 27 bayt

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

Çevrimiçi deneyin!

Kodlanmamış bayt dizisini girdi olarak alan ve kodlanmış bayt dizisini döndüren monadik bir bağlantı. Kurallara göre, son kare işareti atlanmıştır.

açıklama

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 karakter

Son test durumunun sonucunun wiki ve diğer dillerden farklı olduğuna dikkat edin. Bunun nedeni, bu göstergenin sınırdaki 254. sıfır bayt olmasıdır. Özel bir durum olarak ele alınmazsa işler çok daha kolaylaşır.

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

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

Çevrimiçi Deneyin


Son satırın sonundaki arka boşluğu kaldırarak 1 bayt düşürebilirsiniz .
ouflak
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.