전신 골프 : Baudot 코드 해독


31

배경

1870 년 Émile Baudot는 전신용 고정 길이 문자 인코딩 인 Baudot Code를 발명했습니다 . 그는 단지 5 개의 키로 수동 키보드에서 입력 할 수 있도록 코드를 설계했습니다. 두 개는 왼손으로 작동하고 세 개는 오른쪽으로 작동했습니다.

Baudot 5 키 키보드

오른쪽 검지, 가운데 및 약지 손가락은 각각 I , IIIII 키를, 왼쪽 검지 및 가운데 손가락은 IVⅤ를 작동합니다 . (따라서 나는 서양 아라비아 숫자, 즉 1 에서 5까지를 사용할 것이다.) 문자는 코드로 입력된다. 예를 들어, 문자 "C"를 입력하려면 조작자가 1 , 34를 누릅니다.이때, 회전 브러시 암은 각각의 키를 순차적으로 판독하고 전류를 누르거나 누르지 않은 키에 대해서는 전류를 전송하지 않는다. 결과적으로 현대 용어로 5 비트 최하위 비트 우선 이진 인코딩이되는데, 여기서 "C"는로 인코딩됩니다 10110.

5 비트 ??

최대 32 개의 고유 한 기호를 표현할 수있는 5 비트는 영어 문자와 숫자로도 구두점을 표현하기에 충분하지 않다고 생각할 수 있습니다. Baudot는 자신의 소매를 속임수로 만들었습니다. 그의 문자 세트는 실제로 두 개의 고유 한 세트입니다 : Letters and Figures . Letters 모드로 전환되는 Letter Shift5 키 ( 00001) 만 누르면 활성화되고 Figure Shift4 키 ( 00010)로 활성화됩니다 .

도전

당신의 도전은 Baudot 코드 전송을 디코딩하는 프로그램이나 기능을 작성하는 것입니다.

실제 전송은 일부 초기화 비트와 각 문자 전후의 시작 및 정지 비트로 시작하지만 그 문자를 건너 뛰고 각 문자에 대해 5 개의 고유 비트 만 걱정합니다. 입력 및 출력 형식은 아래에 설명되어 있습니다.

바우도의 코드

Baudot 코드에는 두 가지 버전이 있습니다. Continental 및 UK Baudot의 기본 프랑스어에서 "É"와 같은 문자를 포함 하지 않는 영국 버전을 사용합니다 . 또한 인쇄 가능한 ASCII 문자에 속하지 않는 영국 버전의 모든 기호는 생략합니다. 아래 표의 문자 만 디코딩하면됩니다. 표 아래에 설명 된 마지막 3 개의 제어 문자를 제외한 모든 문자는 인쇄 가능한 ASCII 문자입니다.

"Ltr"열은 문자 모드의 문자를 나타내고 "Fig"는 숫자 모드 문자를 나타냅니다.

        Encoding             Encoding
Ltr Fig  12345       Ltr Fig  12345
--- --- --------     --- --- --------
 A   1   10000        P   +   11111
 B   8   00110        Q   /   10111
 C   9   10110        R   -   00111
 D   0   11110        S       00101
 E   2   01000        T       10101
 F       01110        U   4   10100
 G   7   01010        V   '   11101
 H       11010        W   ?   01101
 I       01100        X       01001
 J   6   10010        Y   3   00100
 K   (   10011        Z   :   11001
 L   =   11011        -   .   10001
 M   )   01011        ER  ER  00011
 N       01111        FS  SP  00010
 O   5   11100        SP  LS  00001
 /       11000

오른쪽 열의 마지막 세 행은 제어 문자입니다.

  • ER이다 소거가 . Baudot의 전신 기계는이 문자에 별표와 같은 기호를 인쇄하여 독자에게 선행 문자를 무시해야한다고 알려주지 만, 독자에게는 더 좋으며 실제로는 선행 문자를 생략 (인쇄하지 않음) 할 것 입니다. 문자 및 그림 모드에서 모두 동일하게 작동합니다.

  • FS이다 그림 이동 . 문자 세트를 문자에서 그림으로 전환합니다. 디코더가 이미 그림 모드 인 경우 FS는 공백으로 처리됩니다 ( SP"Ltr"열의 에거). 디코더가 피겨 모드에있을 때 LS 문자가 수신 될 때까지 피겨 모드를 유지합니다.

  • LS입니다 편지 이동 . 문자 세트를 문자에서 문자로 전환합니다. 디코더가 이미 문자 모드 인 경우 LS는 Space 로 처리됩니다 . 문자 모드에있을 때 디코더는 FS 문자가 수신 될 때까지 문자 모드를 유지합니다.

디코더는 항상 레터 모드에서 시작합니다.

Figure Shift, Letter Shift 및 Space를 사용한 예는 다음과 같습니다.

01011 10000 00100 00001 00010 10000 11100 00001 10101 11010
  M     A     Y   LS/SP FS/SP   1     5   LS/SP   T     H

메시지가 나타납니다 MAY 15TH. 보시다시피 00001, 디코더가 이미 문자 모드에 있기 때문에 첫 번째 (Letter Shift / Space) 문자는 공백으로 작동합니다. 다음 문자 00010(그림 이동 / 공간)는 디코더를 그림 모드로 전환하여 인쇄 15합니다. 그런 다음 00001다시 나타나지만 이번에는 문자 이동으로 작동하여 디코더를 문자 모드로 되돌립니다.

편의상 다음은 편집기에서보다 쉽게 ​​요약 할 수있는 형식의 문자입니다 (코드별로 정렬).

A,1,10000|E,2,01000|/,,11000|Y,3,00100|U,4,10100|I,,01100|O,5,11100|FS,SP,00010|J,6,10010|G,7,01010|H,,11010|B,8,00110|C,9,10110|F,,01110|D,0,11110|SP,LS,00001|-,.,10001|X,,01001|Z,:,11001|S,,00101|T,,10101|W,?,01101|V,',11101|ER,ER,00011|K,(,10011|M,),01011|L,=,11011|R,-,00111|Q,/,10111|N,,01111|P,+,11111

입력

입력은 가장 중요하지 않은 비트의 첫 번째 순서로 문자열, 배열 또는 비트 목록이됩니다. 각 문자는 5 비트의 5 중주로 표시됩니다. 비트는 전송의 비트에 직접 매핑 되는 한 이진 문자열, 0s 및 1s 배열 , 문자열 "0""1"문자, 단일 매우 큰 수 등과 같은 임의의 합리적인 형식 일 수 있습니다.

모든 전송에는 적어도 하나의 인쇄 가능한 5 중주와 최대 255 개의 5 중주 (인쇄 가능 또는 기타), 즉 5–1,275 비트가 포함됩니다.

입력은 두 개의 허용 된 예외를 제외하고 전송 비트 포함 할 수 있습니다 . 임의의 수의 선행 또는 후행 0비트 및 / 또는 문자열 입력의 경우 단일 후행 줄 바꿈이 전송에 추가 될 수 있습니다. 선행 또는 후행 비트 또는 문자 각 5 중주 전후에 추가 할 수 없습니다. 즉, 5 중 정수 유형이 아닌 경우 각 5 중주를 8 비트로 채울 수 없습니다 (또는 배열에서 각 5 중주를 단일 숫자로 사용할 수 없음). 추가 비트가있는 5 중주, 예 "01111\n11100".

노트 및 엣지 케이스

  1. 전송에는 위 표의 "Ltr"및 "Fig"열에있는 문자 만 포함됩니다. 01110"그림"열에 없기 때문에 예를 들어 그림 모드에서는 수신되지 않습니다 .

  2. 디코더는 전송 시작시 항상 레터 모드에 있다고 가정합니다. 그러나 첫 번째 문자 바로 그림 모드로 전환하는 FS 문자 일 있습니다.

  3. 디코더가 문자 모드에있을 때, LS 문자를 수신 할 수 있고, 숫자 모드에있을 때 FS 문자를 수신 할 수 있습니다. 두 경우 모두 공백 문자를 인쇄해야합니다 (출력 참조).

  4. ER 문자는 전송에서 첫 번째 문자가 아니며 LS, FS 또는 다른 ER을 즉시 따르지 않습니다.

  5. FS 문자는 LS 문자 바로 뒤에 올 수 있으며 그 반대도 마찬가지입니다.

  6. LS 또는 FS 문자는 전송의 마지막 문자가 아닙니다.

  7. /-문자는 어느 문자 모드 (코드에서 수신 될 수 1100010001각각) 또는도 모드 ( 1011100111).

산출

출력은 ASCII (또는 표현 된 모든 문자가 ASCII와 동일한 UTF-8) 인 가장 합리적인 형식의 형식 일 수 있습니다. 출력이 다른 인코딩 또는 형식 인 경우 답변에 표시하십시오.

노트

  • 공백 문자 (위 3. 참조)는 ASCII 공백 (0x20)이거나 인코딩과 동등한 문자 여야합니다. 즉, 스페이스 바를 누를 때 얻는 문자입니다.

승리

이것은 입니다. 바이트 단위의 가장 짧은 코드가 이깁니다.

제한 사항

  • 표준 허점은 금지되어 있습니다.

  • 후행 공백 및 / 또는 단일 후행 줄 바꿈이 허용됩니다. 선행 공백이나 다른 문자 (전송에 포함되지 않은)는 허용되지 않습니다.

  • Baudot 코드 (또는 Murray 코드, ITA-1 등의 하위 항목)를 디코딩하는 내장 또는 라이브러리 기능을 사용할 수 없습니다.

테스트 사례

Input: 001101000010100111101110010101
Output: BAUDOT
Input: 11010010001001100011110111101111100
Output: HELLO
Input: 01011100000010000001000101000011100000011010111010
Output: MAY 15TH
Input: 0001000100010000001000001011101110011100101010010110101010001111100101
Output: 32 FOOTSTEPS
Input: 10110000110101011100111100001111011010000001101110
Output: GOLF
Input: 000100011000001111100000100010110111001100010110010000111111
Output: 8D =( :P
Input: 0000100001000010000100010001111011111011000011100010001
Output (4 leading spaces):     -/=/-


1
참고 : 테스트 사례를 직접 인코딩했습니다. 잘못 보이는 것이 있으면 말하십시오.
Jordan

1
코드 표와 함께 제공되는 다이제스트에서 코드 00010SP문자 모드와 FS그림 모드 로 나열 됩니다. 설명에 따르면 문자 모드에 있고 code를 받으면 00010그림 모드로 전환해야하지만 테이블의 값이 다른 것처럼 보입니다. 또한의 반대의 경우도 마찬가지입니다 00001.
Sok

3
이 사람은 꽤 똑똑 했어요, 전 전신에 사용 된 압박에 대해 몰랐어요. 역사 수업 담당자에게 감사합니다.
Magic Octopus Urn

4
@carusocomputing 오른쪽 ?? Baudot는 초등학교 이외의 정식 교육을받지 않았지만 Baudot Code를 발명했을뿐만 아니라 4 명의 운영자가 단일 전신선을 동시에 사용할 수있는 다중화 시스템을 발명했습니다. 나는 그의 흥미를 아주 흥미롭게 묘사 한 1919 년 팜플렛을 발견했다 : samhallas.co.uk/repository/telegraph/b6_baudot_multiplex.pdf
Jordan

답변:


6

Pyth, 98 97 95 93 90 83 80 바이트

이 코드에는 인쇄 할 수없는 문자가 포함되어 있으므로 뒤집을 수있는 xxd16 진수 덤프는 다음과 같습니다.

00000000: 753f 7133 4a69 4832 5047 2b47 3f3c 334a  u?q3JiH2PG+G?<3J
00000010: 4040 6332 2e22 275a 75ae 5751 fb4e 3cd7  @@c2."'Zu.WQ.N<.
00000020: 02ce 8719 aac1 e0e0 fe1f 09e5 85bc a767  ...............g
00000030: 8e0c 1f47 508a cad1 1acb b26f 951e e5d6  ...GP......o....
00000040: 225a 4a2a 5c20 715a 3d5a 744a 637a 356b  "ZJ*\ qZ=ZtJcz5k

온라인으로 사용해보십시오. 테스트 스위트.

꽤 긴하지만, 조회 테이블 차지 않는 대부분의 공간의 절반을.

117 바이트의 경우 인쇄 할 수없는 요소가 없습니다 (ISO-8859-1 필요).

u?q3JiH2PG+G?<3J@@c2."'Zu®WQûN<×\x02Î\x87\x19ªÁààþ\x1f\tå\x85¼§g\x8e\x0c\x1fGP\x8aÊÑ\x1a˲o\x95\x1eåÖ"ZJ*\ qZ=ZtJcz5k

또는 조회 테이블에서 압축되지 않은 93 바이트의 경우 :

u?q3JiH2PG+G?<3J@@c2"OVDPYSBREXGMIWFNA-JKUTCQ/ZHL5'0+3;8-2;7);?;;1.6(4;9/;:;="ZJ*\ qZ=ZtJcz5k

5

자바 스크립트 (ES6) 160 158 153 바이트

let f =
    
s=>s.replace(/.{5}/g,s=>(n='0b'+s-1)<2?m-n?(m^=1,''):' ':"? !YSBREXGMIWFNA-JKUTCQ/ZHLOVDP? ?!3 8-2 7) ?  1.6(4 9/ : =5'0+"[n+m*32],m=0).replace(/.!/g,'')

console.log(f("001101000010100111101110010101"));
console.log(f("11010010001001100011110111101111100"));
console.log(f("01011100000010000001000101000011100000011010111010"));
console.log(f("0001000100010000001000001011101110011100101010010110101010001111100101"));
console.log(f("10110000110101011100111100001111011010000001101110"));
console.log(f("000100011000001111100000100010110111001100010110010000111111"));
console.log(f("0000100001000010000100010001111011111011000011100010001"));


5

배치, 306304 바이트

@echo off
set/pc=
set r=
set d=! !!YSBREXGMIWFNA-JKUTCQ/ZHLOVDP!! !3!8-2!7)!?!!1.6(4!9/!:!=5'0+
set s=2
:l
set/an=(s^&32)+0%c:~,2%%%6*8+0x%c:~2,3%%%14
set c=%c:~5%
if %n%==%s% set/as^^=35&goto l
call set r=%%r%%%%d:~%n%,1%%
if %r:~-1%==! set r=%r:~,-2%&goto l
if not "%c%"=="" goto l
echo %r%

STDIN에서 입력을받습니다. Batch에는 이진 변환이 없으므로 8 진수 및 16 진 변환을 사용하여 가짜로 변환해야합니다.

  • 처음 두 자리는 8 진수로 변환됩니다 (첫 번째 자리는이므로 십진수를 사용할 수 없습니다 0). 가능한 값은00 , 01, 1011. 후자의 두 가치가 8하고 9있지만 원하는 2또는 3내가 나머지 모듈을 6.
  • 마지막 3 자리 숫자는 16 진수에서 변환됩니다. 나머지 모듈러스 ( )를 취하기 위해 숫자는 원하는 값 14또는 252시간 입니다.14252=14*18
  • c 코드화 된 문자열
  • r 지금까지 결과는
  • d 디코딩 배열입니다
  • s 시프트 상태를 전환하는 문자의 인덱스 (시프트 상태 고려)
  • n는 이진 디코딩 더하기 비트 5의 비트로 s, 시프트 상태와 같거나,이 경우 시프트 상태가 토글되거나, 다음 문자를 찾기 위해 디코딩 배열로 색인화합니다 (또는!).

3

PHP, 206 바이트

foreach(str_split($argv[1],5)as$s)($k="# f*YSBREXGMIWFNA-JKUTCQ/ZHLOVDP#l *3#8-2#7)#?##1.6(4#9/#:#=5'0+"[32*$f+bindec($s)])=="*"?array_pop($a):($k=="f"?$f=1:($k=="l"?$f=0:($k=="#"?:$a[]=$k)));echo join($a);

2

, 1069 바이트

대단하지만 글쓰기가 즐거웠습니다.

의 문자열로 입력을 받아 "1"'s와 "0"의. (실제로는 낮은 비트 만 봅니다.)

 AZZZZ,-o.AZZZZ  AZZZZ,o-.AZZZZ
*\\\\\]oo[\/\\\**//\\\]oo[/\\\\*
*\\\\/]oo[\/\\/**//\\/]oo[/\\\/*
*\\\//]oo[\/\//**//\//]oo[/\\//*
*\\\/\]oo[\/\/\**//\/\]oo[/\\/\*
*\\//\]oo[\///\**////\]oo[/\//\*
*\\///]oo[\////**/////]oo[/\///*
*\\/\/]oo[\//\/**///\/]oo[/\/\/*
*\\/\\]oo[\//\\**///\\]oo[/\/\\*
=
        o--------K-----o
      ,oo.   z---+~S  ,oo.
     ,LooR. !ZZZZ'   ,LooR.
    ,LLooRR.        ,LLooRR.
   ,LLLooRRR.      ,LLLooRRR.
  ,LLLLooRRRR.    ,LLLLooRRRR.
 ,LLLLLooRRRRR.  ,LLLLLooRRRRR. ,~Z
,LLLLLLooRRRRRR.,LLLLLLooRRRRRR.>m'
|||||||oo||||||||||||||oo||||||)/Rz.
xxxxxxxxxxxxxxx)xxxxxxxxxxxxxxxx\^-^S
x)x))))))))))))xx)))))))))))))xx\g
xx)xxxxxxxxxxxxxxxxxxxxxxxxxxx))\f
xxxxxx))xxxxxxxxxxxxx)))))))))xx\e
xx)x))x)xxxxx))x)))))xxxxxxx)))x\d
xx))x))xxx)))xxxxx)))xxxx)))xx)x\c
xx)xx)xx))x))x)xx)xx)xx))x))x)xx\b
x)))))))x)xx)xxxx)x)xx)x)xx)xx)x\a
x)x)x))))))x)x))x)))x)))xx))x))x/f
x)x)x))))))x)x)xxx)xxxxxxxx)x)xx/e
xxxxxxxx))xxxxxx))))x)))xxx)x))x/d
xxxxx))xxxxx)x)xxx)xxx))xx))xx)x/c
xxx)xxx)xxxx)x)xxxxxx))xxx))x))x/b
x)xxx)x)x)xx)xxxxx))x)))xx))xxxx/a

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

참고 : Erasure는 ASCII 백 스페이스 문자 ( \x08)를 사용합니다. 즉, TIO에서는 재미있게 보이지만 xterm에서는 잘 보입니다.

기본 구조

=라인 위의 맨 위에는 입력 디코더가 있습니다. 입력을 32 개의 개별 신호 중 하나로 바꿉니다. o위의 =에서 아래 로 전송 됩니다.

의 삼각 산 L의와 R의는 열에 별도의 행에서 패턴을 회전 할 수 있습니다. 아래 표는 각 열을 출력 문자로 변환합니다. 알 수없는 신호의 경우 NUL (\x00 )이 생성됩니다. 특수 이동의 경우 문자를 인쇄하는 대신 오른쪽의 작은 얼룩이 모드를 변경합니다.

두 산 사이의 케이블카와 같은 것은 각 5 중주 사이의 인쇄를 억제합니다. 그렇지 않으면 모든 중첩 5 중주도 해독하려고합니다. !이것을 공백으로 교체하여 직접 확인하십시오. ( -v여기서 상세 모드로 실행하는 것도 좋습니다.)

현재로서는 이것을 더 작게 만드는 방법을 잘 모르겠습니다. 이미 그 크기에 비해 밀도가 높습니다.


0

GNU sed, 334 + 1 = 335 바이트

-r플래그의 경우 +1 바이트 STDIN에서 입력을받습니다.

오래된 과제를 살펴보면 sed를 사용하면 매우 쉽고 연습에 도움이된다는 것을 알았습니다. 압축을 시도하지 않았으므로 조회 테이블이 코드의 절반 이상입니다.

s|.*|#@&;01000E211000/%00100Y310100U401100I%11100O500010f 10010J601010G711010H%00110B810110C901110F%00001 l10001-.01001X%11001Z:00101S%10101T%01101W?11101V'00011<<10011K(01011M)11011L=00111R-10111Q/01111N%11111P+10000A111110D0|
:
s/@([01]{5})(.*;.*\1)(..)/\3@\2\3/
t
s/@;.*//
s/#f /@/
s/@ l/#/
s/#(.)./\1#/
s/@.(.)/\1@/
t
s/.<|[#@]//g

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

설명

이 코드는 두 단계로 작동합니다. 먼저, 이진 숫자의 각 실행을 조회 테이블의 해당하는 두 문자 (문자 및 그림)로 바꿉니다. 룩업 테이블의 형식은 𝟎𝟎𝟎𝟎𝟎𝐋𝐅𝟎𝟎𝟎𝟎𝟎𝐋𝐅…입니다. 여기서 𝟎는 이진수이고 𝐋 및 𝐅는 각각 해당 문자와 ​​그림입니다. %누락 된 문자를 나타냅니다 (이는 개행 문자 이외의 다른 문자 일 수 있음). FS/SP로 표시 f<space>하고 SP/LS있다 <space>l. ER로 표시됩니다 <<.

그런 다음 현재 모드 ( #문자 모드, @그림 모드)에 해당하는 "커서"로 각 쌍을 단계별로 실행 합니다. #커서 쌍의 두 번째 문자를 제거하고 다음 쌍으로 진행하고,이 @제 발전을 제거한다. 즉, #A1B8하게 A#B8하고 AB#, 그리고 @A1B8이된다 1@B8다음과 18@. #커서가 발생 하면 커서가 f<space>삭제 되고 커서로 대체 @되고 그 반대도 @발생 <space>l합니다.

쌍이 남아 있지 않으면 마지막 커서가 뒤에 문자와 함께 제거됩니다 <.

# Setup: Append a lookup table to the line.
# Also prepends "#" and "@" which we'll use as "cursors" later.
s|.*|#@&;01000E211000/%00100Y310100U401100I%11100O500010f 10010J601010G711010H%00110B810110C901110F%00001 l10001-.01001X%11001Z:00101S%10101T%01101W?11101V'00011<<10011K(01011M)11011L=00111R-10111Q/01111N%11111P+10000A111110D0|

# Phase 1
:
  # Using "@" as a "cursor", substitute for each run of 5 binary digits the
  # two corresponding characters from the lookup table.
  s/@([01]{5})(.*;.*\1)(..)/\3@\2\3/
  t   # Loop (branch to `:`) as long as substitutions are made.

s/@;.*//       # Delete the "@" and lookup table

# Phase 2
s/#f /@/       # FS (f ) in letter mode (#); delete and switch to figure mode (@ cursor).
s/@ l/#/       # LS ( l) in figure mode (@); delete and switch to letter mode (# cursor).
s/#(.)./\1#/   # Letter mode; replace pair with first of pair; advance cursor.
s/@.(.)/\1@/   # Figure mode; replace pair with second of pair; advance cursor.
t              # If any substitutions were made, branch (loop) to `:`.

# Teardown
s/.<|[#@]//g   # Delete characters followed by < (ER) and cursor.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.