시저 이동


13

기술

Caesar Shift는 매우 간단한 단일 알파벳 암호로 각 문자는 알파벳에서 그 다음 문자로 바뀝니다. 예:

Hello world! -> IFMMP XPSME!

( IBSLR, EGUFV!실제 챌린지에 대한 출력입니다. 이것은 1만큼 이동 한 예입니다.)

보시다시피 간격과 문장 부호는 조정되지 않은 상태로 유지됩니다. 그러나 메시지를 추측하지 못하도록 모든 문자는 대문자로 표시됩니다. 문자를 되 돌리면 메시지가 해독되고 편리하지만 메시지의 의미를 모르는 다른 사람들이 해독하기가 쉽습니다.

그래서 우리는 고급 형태의 암호를 사용하여 Caesar를 조금 도와 줄 것입니다 : Self-shifting Caesar Shift !

도전

당신의 임무는 암호화 할 문자열이 입력에 해당하는 프로그램을 작성하는 것입니다. 고급 시저 시프트는 다음과 같이 작동합니다.

1. Compute letter differences of all adjacent letters: 
    1.1. Letter difference is computed like this:

         Position of 2nd letter in the alphabet
        -Position of 1st letter in the alphabet
        =======================================
                              Letter difference

    1.2. Example input: Hello
         H - e|e -  l|l  -  l|l  -  o
         7 - 5|5 - 12|12 - 12|12 - 15 Letter differences: 3; -7; 0; -3
            =3|   =-7|     =0|    =-3

2. Assign the letters continously a letter difference from the list,
   starting at the second letter and inverting the differences:
    2.1. 2nd letter: first difference, 3rd letter: second difference, etc.

    2.2. The first letter is assigned a 1.

    2.3. Example input: Hello with differences 3; -7; 0; -3

         Letter || Value
         =======||======
            H   ||   1
            E   ||  -3
            L   ||   7
            L   ||   0
            O   ||   3

3. Shift the letters by the value x they have been assigned:
    3.1. In case of a positive x, the letter is shifted x letters to the right.
    3.2. In case of a negative x, the letter is shifted |x| letters to the left.
    3.3. In case of x = 0, the letter is not shifted.

    3.4. If the shift would surpass the limits of the alphabet, it gets wrapped around
         Example: Y + Shift of 2 --> A

    3.5. Example input: See the table under 2.3.

                ||       || Shifted
         Letter || Value || Letter
         =======||=======||=========
            H   ||   1   ||    I
            E   ||  -3   ||    B     Program output:
            L   ||   7   ||    S     IBSLR
            L   ||   0   ||    L
            O   ||   3   ||    R

이 프로세스에서는 공백 및 구두점과 같은 기타 특수 기호를 건너 뜁니다. 프로그램에는 인쇄 가능한 ASCII 문자 만 포함 된 문자열이 제공됩니다. 함수 / 프로그램의 출력은 대문자 여야합니다.

이것은 이므로 표준 허점이 적용되며 바이트 단위의 최단 답변이 이길 수 있습니다!


2
아닌가요 E -3?
Leaky Nun

3
글자 차이가 알파벳에서 글자를 가져 오면 어떻게됩니까? 마찬가지로 ZEN, 예를 들어. Z1만큼 이동하면 ... A? (부수적으로, 05AB1E 답변은 Z로 바 A))
Mr. Xcoder

6
테스트 케이스주세요. 또한 정확히 어떤 문자를 건너 뛰나요? 그리고 그들이 건너 뛴다는 것은 무엇을 의미합니까? 그것들이 완전히 제거 되었습니까, 아니면 출력물에 남아 있어야합니까?
Luis Mendo

1
@Giuseppe는 테스트 사례에 대한 upvoted 답변을 보았으며 OP에 의해 올바른 것으로 확인되었거나 추측하거나 다운 투표를했습니다.
매직 문어 Urn

2
당신은 같은 단어를 찾으셨습니까 RELIEFRELIES같은 결과에 모두 암호로 바꾸다에 SRSFAG?
Anders Kaseorg

답변:


5

05AB1E , 28 27 24 바이트

láÇ¥R`XIlvyaiAyk+Aèëy}u?

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

설명

l                          # convert input to lower case
 á                         # keep only letters
  ǥ                       # compute deltas of character codes
    R`                     # reverse and push separated to stack
      X                    # push 1
       Ilv                 # for each char y in lower case input
          yai              # if y is a letter
             Ayk           # get the index of y in the alphabet
                +          # add the next delta
                 Aè        # index into the alphabet with this
            ëy             # else push y
              }            # end if
            u?             # print as upper case

우리 모두 GET IBSLR, EGUFV!을 위해 Hello, World!, 맞습니까? OP가 그 예를 엉망으로 만들었습니까?
매직 문어 Urn

1
@MagicOctopusUrn : 처음에 그의 예제는 변화가 무엇인지 보여주는 것입니다. 그것은 단지 1 글자만큼 이동하므로 오해의 소지가 있습니다.
Emigna

4

파이썬 3 , 100 바이트

b=0
for c in map(ord,input().upper()):
 if 64<c<91:b,c=c,(c+c-(b or~-c)-65)%26+65
 print(end=chr(c))

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

b마지막 문자의 ASCII 코드를 추적하거나 처음에는 0입니다. 수식 c+c-(b or~-x)은 ASCII 코드 c가 있는 문자가 if 가 0이 아닌 경우 와 if 가 0 (첫 번째 문자의 c-b경우 b) 만큼 이동 함을 의미합니다 .c-(c-1) == +1b

b문자열은 인쇄 가능한 ASCII 문자 로 구성되어 있으므로 다시는 0이되지 않습니다 .

마지막으로 대문자 ASCII 문자 64<c<91인지 확인 c하고 (…-65)%26+65모든 것을 A-Z범위 로 래핑 합니다.

ovs는 바이트를 저장했습니다. 감사!





1

MATL , 27 바이트

tXkt1Y2mXH)tlwdh+64-lY2w)H(

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

나는 이것이 내가 얻을 수있는 가장 짧은 것이라고 생각하지만 '변수'(3 t(중복) 및 2 w(스왑) 작업 H이 많이 사용되므로 클립 보드 가 사용 되므로 다양한 품종이 많이 있습니다. 그럼에도 불구하고 여전히 중복이 있습니다 1Y2...). 슬프게도 자동 M클립 보드로 바이트를 저장할 수 없었습니다 .

프로그램의 절반 이상이 대문자로되어 있고 알파벳이 아닌 문자를 무시하는 데 전념하고 있습니다. 암호는 13 바이트를 넘지 않아야합니다 ( 온라인으로 시도하십시오! )


1

펄, 90 89

비 codegolf 언어는 경쟁력이 거의 없지만 100 이하로 떨어질 수 있습니다.)

@a=split//,<>;say uc(++$a[0]).join'',map{uc chr(2*ord($a[$_+1])-ord($a[$_])+!$_)}0..$#a-1

나는 이것을 풀기로 결정했다.

@a = split//,<>; STDIN에서 입력을 받아 @a에 문자 목록 (줄 바꾸기!)을 저장합니다.

say uc(++$a[0])접두사 ++를 사용하면 펄 단위로 문자를 증가시킬 수 있습니다. 이것은 c의 뮤 테이터입니다.

2*ord($a[$_+1])-ord($a[$_])+!$_우리는 x에서 문자를 취하고 차이 + (x- (x-1))를 추가하도록 요청받습니다. 2x-(x-1)입니다. 그러나 첫 글자를 바꿨습니다! 따라서이 오류를 수정해야하므로 +!$_0 위치에서 하나를 너무 많이 빼면 수정됩니다 (! $ _ 만 undef 경우가 아닙니다). 그런 다음 uc chr계산 된 ASCII 값에서 대문자를 가져옵니다.

map{ ... } $#a-2- $#a는 마지막 배열 요소에 액세스 할 수있는 위치입니다. 내가 원하는 것을 추가 $#a-1하기 때문에 입력의 개행을 무시해야하기 때문에 이것은입니다 $#a-2.

이것은 첫 번째 편지와 연결되어 있으며 완료되었습니다 :)


이것은 알파벳과 알파벳이 아닌 문자를 감싸는 오프셋을 처리하는 데 문제가있는 것으로 보입니다. 온라인으로 사용해보십시오!
Xcali

1

Perl 5 -F , 73 77 74 바이트

/\w/&&($_=chr 65+(2*($n=ord uc)-65-($!||-1+ord uc))%26)&($!=$n)for@F;say@F

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


이것은 비 편지를 완전히 건너 뛰지는 않습니다. 그냥 변환하지 않습니다. 나는 Hello, World!결과가 IBSLR, EGUFV!아니라고 생각 한다 IBSLR, XGUFV!.
Titus

네가 옳아. 이전 문자를 보존하기 위해 4 바이트 더 고정했습니다.
Xcali

1

PHP, 106 98 바이트

꽤 불쾌한 ... ... 그냥 base_convert길지 않은 경우 (또는 ctype_alpha) ...
하지만 100 미만으로 받았습니다. 만족합니다.

for(;$a=ord($c=$argn[$i++]);print ctype_alpha($c)?chr(65+($p?(25-$p+2*$p=$a)%26:$p=$a)):$c)$a&=31;

파이프로 실행 -nR하거나 온라인으로 사용해보십시오 .


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.