일관된 오버 헤드 바이트 스터핑 (COBS)


10

이전에 게시되지 않은 것에 대해 놀랐습니다!

일관성 오버 헤드 바이트 스터핑 (옥수수 속) 알고리즘를 단락 바이트 스트림으로 사용된다.

프레임 마커를 선택하고 (0x00 사용) 스트림에서 0x00이 발생하는 곳마다 다음 0x00이 발생할 때까지 바이트 수로 바뀝니다 (이것을 마일스톤이라고 함). 이렇게하면 값 범위가 0..255에서 1..255로 줄어들어 0x00이 스트림의 프레임을 명확하게 구분할 수 있습니다.
이정표에서 다음 255B에 0x00이 포함되어 있지 않으면 최대 이정표 길이를 초과합니다. 알고리즘은 255B에서 '중지'되어 다른 이정표를 작성해야합니다. 이것이 '일관된 오버 헤드'입니다.
첫 번째 바이트는 첫 번째 이정표가되고 마지막 이정표는 프레임 마커까지의 바이트 수입니다.

Wikipedia의 몇 가지 예 (색칠 된 기사를 읽는 것이 가장 좋습니다) :

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

도전 과제 : 가장 짧은 프로그램에서 이것을 구현하는 것.

  • 입력이 인코딩되지 않은 바이트 스트림 / 배열, 출력이 인코딩 된 바이트 스트림 / 배열
  • 모든 종류의 이진 표준 입 / 출력 사용
  • 최종 프레임 마커는 필요하지 않습니다
  • 프로그램은 대형 배열을 반환 할 수 있습니다
  • 0이 아닌 254 바이트로 끝나는 스트림에는 후행 0x00이 필요하지 않습니다.

노트

  • 최악의 경우 반환 길이는 numBytes + (numBytes / 254) + 1

바이트 배열이 있습니다

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

각각에 대해 0x00우리는 다음 단계 0x00가 어디 였는지 언급해야합니다.

[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
스펙에 이것을 포함시켜야합니다 . 특별한 예외로, 패킷이 0이 아닌 254 개의 그룹으로 끝나는 경우 후행 0 바이트를 추가 할 필요가 없습니다. 일부 상황에서는 1 바이트가 절약됩니다. (Wikipedia 인용)
Arnauld

3
@LuisMendo 동의합니다. 이제 모든 테스트 사례를 살펴 보았으므로 현재 약간 미달되었음을 확인할 수 있습니다.
Arnauld

@Arnauld, 나는 엔드 프레임 제작자가 어쨌든 필요하지 않다고 말했다 :)
Patrick

이 예에서, 실수하지 않는 한 첫 번째 출력 바이트는 0x02가 아닌 0x03이어야합니다.
Olivier Grégoire

1
0이 아닌 254 바이트로 끝나는 특별한 경우에 관한 @Arnauld : 동의합니다. 이것은 최종 프레임 마커에 대한 별도의 문제입니다. 그렇기 때문에 여섯 번째 예제에는 후행이 01없지만 01아홉 번째 예제 에는 두 개의 s가 있습니다 (0이 아닌 254 바이트와 0이 있음).
Nick Kennedy

답변:





1

젤리 , 27 바이트

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

온라인으로 사용해보십시오!

인코딩되지 않은 바이트 배열을 입력으로 받아서 인코딩 된 바이트 배열을 반환하는 모나드 링크. 규칙에 따라 최종 프레임 마커는 생략됩니다.

설명

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 자

마지막 테스트 사례의 결과는 Wiki 및 기타 언어와 다릅니다. 이것은 경계에서이 254 번째 영 바이트를 가리키는 포인터 때문입니다. 이것이 특별한 경우로 취급되지 않으면 상황이 훨씬 쉬워집니다.

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

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

온라인 시도


마지막 줄의 끝에서 후행 공백을 제거하여 1 바이트 를 줄일 수 있습니다 .
ouflak
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.