시저-사이퍼-마니아


22

시저 사이퍼는 각 문자는이 (A 주위로 루핑 Z)의 고정 오프셋으로 이동하는 매우 간단한 치환 암호이다. 마찬가지로 인쇄 가능한 ASCII 문자 집합에 대한 시저 암호도 사용할 수 있습니다. 코드 포인트 0x20에서 0x7E까지의 95 자입니다. 주어진 오프셋 d에 대해 코드 포인트 C

(C - 32 + d) % 95 + 32

모든 문자를 a만큼 이동하고 d주위에서 ~공백으로 반복 합니다. 이 범위 밖의 문자 (줄 바꿈, 탭 및 ASCII 범위 밖의 문자와 같은 제어 문자)는 영향을받지 않습니다.

오프셋 d과 문자열 을 취하는 두 개의 프로그램 또는 함수 (잠재적으로 다른 언어로)를 작성해야 합니다. 첫 번째 프로그램은 입력 된 시저 사이퍼를 반환하거나 인쇄해야합니다. 두 번째 프로그램은 시저 사이퍼를 반환하거나 인쇄해야합니다 (즉, offset 사용 -d). STDIN, 명령 행 인수 또는 함수 인수를 통해 입력 할 수 있습니다.

더 흥미롭게하려면 두 번째 프로그램은 첫 번째 프로그램의 시저 사이퍼 여야합니다. 즉, 0이 아닌 오프셋에 대해 첫 번째 프로그램의 소스 코드를 자신에게 전달 d하면 출력은 두 번째 프로그램이어야합니다.

입력 문자열뿐만 아니라 두 프로그램 모두 인쇄 가능한 ASCII 문자, 줄 바꿈 및 탭만 포함해야합니다. 어떤 프로그램도 주석을 포함하거나 자체 소스 코드, 파일 이름 또는 프로세스 ID를 직간접 적으로 읽을 수 없습니다.

이것은 코드 골프이므로 가장 짧은 대답 (바이트)이 이깁니다. 두 프로그램의 크기가 같아야하므로 한 번만 계산하면됩니다.

답변:


12

잼, 40 38 37 바이트

순방향 암호 :

 q~'~),32>_@m<er "o|%|'*10<]>k<cpZ"_-

역 암호 :

"s!)!+.54@aBo>gt"$q~'~),32>_@m>er\$a/

두 번째 프로그램은 첫 번째의 암호입니다. 2


작동 원리

나는 물건을 테스트하면서 순수한 행운에 대한이 답변을 생각해 냈습니다.

먼저, 암호 부분 :

q~'~),32>_@m<er
q~                 "Take the input and evaluate it";
  `~)              "Get the next character after the printable ASCII range";
     ,32>          "Get all printable ASCII characters":
         _@        "Copy the printable ASCII string and bring the cypher difference"
                   "on top of stack";
           m<      "Forward rotate the copy of printable ASCII string by difference";
                   "In case of inverse Cypher, this is m> to reverse rotate the string";
             er    "Transliterate to complete the forward/inverse Cypher";

이제 까다로운 부분에 대한 설명 이옵니다.

주요 변형은

<space> -> "     // Empty space to string conversion
Z -> \           // Character Z in an useless string to swap operation
_ -> a           // Copy operation to wrapping in an array
- -> /           // Set subtraction to string splitting

첫 번째 프로그램은

 q~'~),32>_@m<er "o|%|'*10<]>k<cpZ"_-
 q~'~),32>_@m<er                          "no-op space, Forward cypher, no-op space";
                 "o|%|'*10<]>k<cpZ"       "Useless String (Actually not)";
                                   _      "Copy it and ..."
                                    -     "remove all alphabets of copy from original";

두 번째 프로그램은

"s!)!+.54@aBo>gt"$q~'~),32>_@m>er\$a/
"s!)!+.54@aBo>gt"                       "Cypher of first part of first program"
                                        "with difference of 2";
                 $q~'~),32>_@m>er\$a/   "Cypher of the useless string of first program";
                                        "with difference 2";
                 $                      "Sort the first program's main part's cypher";
                  q~'~),32>_@m>er       "Program to reverse cypher";
                                 \$     "Swap the cypher to the top of stack and sort it";
                                   a    "Wrap it in array";
                                    /   "Split the output string on an array, which";
                                        "always returns the output in an array as there";
                                        "are no occurrences of an array in a string";

입력은 같다 "<escaped string to be cyphered>" <difference>

예를 들면 다음과 같습니다.

"abcd" 4

그리고 첫 번째 프로그램의 출력은

efgh

그리고 두 번째 프로그램은

]^_`

여기에서 온라인으로 사용해보십시오


40 바이트가 아닙니까? 또한 온라인 인터프리터에 오류가 발생합니다 (Arraylists에 구현되지 않은 항목)
Def

@Deformyer가 바이트 수를 수정했습니다. 입력 내용은 무엇입니까?
Optimizer

그래 내 나쁜, 나는 잘못된 순서로 인수를 사용했다.
데프

' "q ~'~), 32> _ @ m <er"9} o | % | '* 10 <]> k <cp}] "_-"2'가 작동하지 않습니다 (java.lang.RuntimeException : 예기치 않은})
데프

1
@Deformyer 해당 문자열에서 따옴표를 피해야합니다
Optimizer

7

파이썬 2, 147

분명히 나는 ​​파이썬에서 쓸모가 없기 때문에 이것에 대해 너무 열심히 생각하지 않았습니다. 사용하지 않는 프로그램을 문자열로 묶은 두 개의 별도 프로그램이 있습니다.

두 프로그램 사이의 오프셋은 39입니다.

앞으로

유니 코드 문자열과 오프셋을 허용하는 함수 Z를 정의합니다.

Z=lambda s,d:s.translate({i+32:(i+d)%95+32for i in range(95)})or u''and Z
"uE:F;=:XLd=rLfMK:GLE:M>`TBckjr`Be=a]qmckj?HKXBXBGXK:G@>`qmaVaHKXN__:G=X"

유니 코드 문자열과 오프셋을 허용하는 함수를 정의합니다.

"d4)5*,)G;S,a;U<:)6;4)<-OC1RZYaO1R,PL`\RZY.7:G1G16G:)6/-O`\PEP7:G=NN)6,G"
I=lambda s,d:s.translate({i+32:(i-d)%95+32for i in range(95)})or u''and I

5

파이썬 3-248 바이트

내 목표는 이것을 파이썬 원 라이너로하는 것이 었습니다. 목표 성공, 그러나 나는 골프를 귀찮게 할 수 없습니다.

암호화 :

r=q="".__doc__[2];eval("p"+q+"int(''.join([c,ch"+q+"((o"+q+"d(c)-32+d)%95+32)][31<o"+q+"d(c)<127]fo"+q+" d in[int(input())]fo"+q+" c in input()))")or'\^UZ`smmyV[UZsGOwOT^ss[^PsOtx~}xPtp%!v~}tIG~|([^PsOt(|}$IR[^kPkUZGUZ`sUZ\a`sttIR[^kOkUZkUZ\a`sttt'

해독 :

'Q&Q66Bssx$wssoFqOy+u!<6%6?&?6}#)<;;B~$}#<ow@w|6?&?6<<$6?&?6x<w=AGF?x=9MI?GF=qoGEP$6?&?6x<w=PEFKqz$6?&?64x4}#o}#)<}#%*)<==qz$6?&?64w4}#4}#%*)<===6=$';print("".join([c,chr((ord(c)-32-d)%95+32)][31<ord(c)<127]for d in[int(input())]for c in input()));

편집 : 인쇄 가능한 ASCII 범위 밖의 문자에 영향을 미치지 않도록 수정되었습니다.

암호화에서 암호 해독까지의 오프셋은 20입니다. 오프셋을 먼저 입력 한 다음 문자열을 입력하여 사용하십시오 (예 :

5
hello

설명

다음과 같은 변형이 핵심입니다.

r -> '
' -> ;

첫 번째는의 사용을 허용하고 or두 번째는 세미콜론으로 문자열을 무시합니다.

에서 가져온 "".__doc__[2]문자열 을 반환합니다 . 이것은 해독 프로그램에서 작은 따옴표로 묶인 문자열이 중간에 흩어져있는 따옴표를 갖지 않도록하기 위해 필요합니다.rstr


5

루비, 131125 바이트

여기 내 자신의 제출물이 있습니다 (이전에 개념 증명으로 작성했지만 어떻게 든 내 자신의 규칙을 위반했습니다). 나는 두 제출 사이에 어떤 코드도 재사용하지 않고 있지만 결국 두 줄로 구성됩니다. 대신 두 줄로 구성되어 있으며 그중 하나는 횡설수설 문자열로 바뀝니다.

순방향 암호 :

Y=->d,s{s.chars{|c|x=c.ord;$><<(x<32?x:(x-32+d)%95+32).chr}};Y
"tdu<cKSKe;@9JKST;TPt;eGJ<r[uss_PsjivPq_Pdjid<`\plbji`e;@JUUr"

역 암호 :

"eUf-T<D<V,1*;<DE,EAe,V8;-cLfddPAd[ZgAbPAU[ZS-QMa]S[ZQV,1;FFc"
J=->d,s{s.chars{|c|x=c.ord;$><<(x<32?x:(x-32-d)%95+32).chr}};J

두 스 니펫 은 정수와 문자열을 가져 와서 변환 된 문자열을 STDOUT에 인쇄 하는 함수 ( Y첫 번째 함수와 두 번째 함수)를 정의합니다 J. 두 코드 사이의 오프셋은 40입니다.


4

oOo CODE , 750 744 바이트, 두 프로그램 모두에서 사용되는 모든 코드

너무 길지만 아마도 그 일을하는 올바른 도구 일 것입니다 ...

암호화 :

CcCcccccccccCcYcccCCCccCcCcCccccccCcCcccccCcCcccCcCccCccCcCCccccCcCccccCCcCccccCCccCccCcCCcccCCCcCccccCcCCcCCcCCcCcCcCccccCCccCccCccCccCccCccCccCccccccCCCcCccCccCCcCcCcccCCcCcccCcCCcCCcCcCCccCCcCCcCCcCCcCCcCCcCCcCCcCCcCCcCcccccccCccccCccccCCccccCCcCccCCcccCccccccccccCcCccCccCccCccCcCCccCCcccCcCcCccCCcccCCCcCcccccccccccccCCccCccCcCcCcccCCccccccccccCcCccccccCcCccccCCcCccCccCCcCccccccccccCCccCcCcCcccccCcCccCcCCCcCccCccCCcCccCccCccCcCcccccCcCcccCCCcCcCccccCcCccCCcCCcCCcCcCCcccCcCCcCCcCCcCCcCCcCCcCCcCCcCCcCcCcccCccCCcccccCcCcccCcccccCcccCcccCccCccCCcCcccccccccccccCCCcccCcCcCcccCcccCCCcCccCccCccCcCCccCccCcCCCcCccccCcCccccccccCcCccCccCcCCccccccCccccccccCcccCCccCccCccCCcCCcCCcCCcCcCcCcccccCcCCcCCcCCcCCcCCcCCcCCcCccCcCCcccCCccCcCcccCCcccCCCcCC

해독 :

SsSsssssssssSsisssSSSssSsSsSssssssSsSsssssSsSsssSsSssSssSsSSssssSsSssssSSsSssssSSssSssSsSSsssSSSsSssssSsSSsSSsSSsSsSsSssssSSssSssSssSssSssSssSssSssssssSSSsSssSssSSsSsSsssSSsSsssSsSSsSSsSsSSssSSsSSsSSsSSsSSsSSsSSsSSsSSsSSsSsssssssSssssSssssSSssssSSsSssSSsssSssssssssssSsSssSssSssSssSsSSssSSsssSsSsSssSSsssSSSsSsssssssssssssSSssSssSsSsSsssSSssssssssssSsSssssssSsSssssSSsSssSssSSsSssssssssssSSssSsSsSsssssSsSssSsSSSsSssSssSSsSssSssSssSsSsssssSsSsssSSSsSsSssssSsSssSSsSSsSSsSsSSsssSsSSsSSsSSsSSsSSsSSsSSsSSsSSsSsSsssSssSSsssssSsSsssSsssssSsssSsssSssSssSSsSsssssssssssssSSSsssSsSsSsssSsssSSSsSssSssSssSsSSssSssSsSSSsSssssSsSssssssssSsSssSssSsSSssssssSssssssssSsssSSssSssSssSSsSSsSSsSSsSsSsSsssssSsSSsSSsSSsSSsSSsSSsSSsSssSsSSsssSSssSsSsssSSsssSSSsSS

Brainfuck 번역 :

+>>>+>,<[->[->+>+<<]>[-<+>]<<]>,[>++++[-<-------->]+<<+[<+>+++]<++++++++++>>[>-<-<+<-[>>>+<<<<]<-[+<-]+>>>>]<<[-]>>>[->[-<+<<+>>>]<[->+<]+<<+<<<[>[-]+[>+<+++]>++++++++++[<<->+>->-[<<<+>>>>]-[+>-]+<<<]<<]+>[->>+<<]>>->>-]<<<++++[->++++++++<]>.[-]>,]
+>>>->,<[->[->+>+<<]>[-<+>]<<]>,[>++++[-<-------->]+<<+[<+>+++]<++++++++++>>[>-<-<+<-[>>>+<<<<]<-[+<-]+>>>>]<<[-]>>>[->[-<+<<+>>>]<[->+<]+<<+<<<[>[-]+[>+<+++]>++++++++++[<<->+>->-[<<<+>>>>]-[+>-]+<<<]<<]+>[->>+<<]>>->>-]<<<++++[->++++++++<]>.[-]>,]

oOo CODE는 대소 문자 만 중요한 Brainfuck 변형입니다.

첫 번째 바이트를 가져 와서 문자 코드를 사용합니다 d(따라서 줄 바꿈은 d = 10을 의미합니다). 나머지 입력은 문자열입니다. EOF는 0입니다.


4

GolfScript, 95 64 바이트, 두 프로그램 모두에서 사용되는 모든 코드

암호화 :

0 0z{ 1)'[}??)9t:z21,--/; [84;%zt*84*84$|)21*|$Z!!\~'---|}`{)}%~

해독 :

1!1{|!2*(\~@@*:u;{32-..0<!\95<&{u+95+95%}*32+}%[""] (...}~a|*~& 

입력 형식 :

1 "0 0z{ 1)'[}??)9t:z21,--/; [84;%zt*84*84$|)21*|$Z!!\~'---|}`{)}%~"

설명

해독 :

1!1                            # Push 0 1.
{                              # Define a block and evaluate it.
    |                          # Or.
    !2*(                       # Get 1 for encryption, or -1 for decryption.
    \~                         # Evaluate the input string.
    @@*:u;                     # u = d for encryption, or -d for decryption.
    {                          # For each character:
        32-                    # Subtract 32.
        ..0<!\95<&             # Test if it is in the printable range.
        {u+95+95%}*            # If so, add u (mod 95).
        32+                    # Add 32 back.
    }%
    [""] (...                  # Push an empty array and 4 empty strings.
}~
a                              # No-op.
|*~                            # Evaluate ""*(""|"") which does nothing.
&                              # Calculate []&"" which is empty.

암호화 :

0 0                            # Push 0 0.
z                              # No-op.
{                              # Define a block and get its string representation.
    ...                        # See decryption code.
    |                          # This will be decoded into a }. The string will be truncated here when evaluated.
}`                             # Only the closing } will be truncated, but it is still used as the end of the block.
{)}%                           # Increment each character. Note that the braces before and after the block will also be incremented.
~                              # Evaluate the string.

3

자바 스크립트 (ES7 초안) - 167 165 바이트

@feersum의 문자열 사용 및 @MartinButtner의 세미콜론 사용에서 차용;)

암호화 :

J=(s,d)=>s.replace(/[ -~]/g,x=>String.fromCharCode((x.charCodeAt()-32+d)%95+32));J
"eP<T-Qef<V;.95*,.PW$HUG&W0TAef{=;270V/;86k1*;k8-.PPAV,1*;k8-.i=PQS^[U-QMa]S[ZQQc"

해독 :

"t_Kc<`tuKeJ=HD9;=_f3WdV5f?cPtu+LJAF?e>JGEz@9JzG<=__Pe;@9JzG<=xL_`djib<`\plbji``r"
Y=(s,d)=>s.replace(/[ -~]/g,x=>String.fromCharCode((x.charCodeAt()+63-d)%95+32));Y

사용 오프셋 : 55


1
빈 문자열에 실패합니다. 그렇기 때문에 내가 or <empty string> and <function>대신 넣어야했습니다 or <function>.
feersum

@feersum 이제 수정되었습니다 ... 2 바이트 더 짧음 :)
nderscore

흠, 이것은 친숙해 보인다. ;)
Martin Ender

@ MartinBüttner 나는 당신이 무슨 뜻인지 모르겠다 ...;)
nderscore

2

> <> (물고기) , 467 바이트

암호화 :

ffii{{~~__:0a('0'*!.0a('0'*22(!'(~$~_:}-}$-a*}+{{if~~:i:0({}?;__:{}84{}*__({}?\__:{} _{}70{}g_{})_{}?\4__{}8*-_{}+{}80{}g_%4_{}8*{}+\\sl||||||||||||||||||||||||||||9||||||||||||||9||||||||||||||||||||||||||||||||||||||||||||||||||||9
                                                                              >                      >                              >!;7f7-_{}!%_{}!<872-d_{}!&_{}!<[755(7(%~~_{}!<[55(7(_{}!*!*23a(_{}!'_{}!"55(7((~~_{}~~~o__'4'0.{{{o,

해독 :

iill~~""bb=3d+*3*-$13d+*3*-55+$*+"'"b=!0!'0d-!.~~li""=l=3+~!B>bb=~!;7~!-bb+~!B_bb=~!#b~!:3~!jb~!,b~!B_7bb~!;-0b~!.~!;3~!jb(7b~!;-~!.__vo                            <              <                                                    <
##############################################################################A######################A##############################A$>:i:0b~!$(b~!$?;:50gb~!$)b~!$?^:88+:+(""b~!$?^88+:+b~!$-$-56d+b~!$*b~!$%88+:++""b~!"""rbb*7*31~~~r/

두 프로그램은 3 씩 오프셋되며 다음과 같은 형식으로 입력됩니다.

<2-digit offset> <text>

오프셋 2 자리 여야 하므로 5의 오프셋을 다음과 같이 입력해야합니다.05 .

이것은 긴 제출이지만, 거의 모든 비 필러 문자는 두 프로그램에서 사용됩니다 . 분명히 골프를 칠 수있는 많은 공백이 있지만 프로그램이 더 재미있을 것이라고 생각했습니다.

이 이미지 는 두 프로그램에서 사용하는 문자를 강조 표시합니다.

설명

이를 가능하게하는 주요 _{} -> b~!구성은입니다. 이는 해독 프로그램에서 임의의 문자를 건너 뛸 수있게합니다. 방법?

Encrypt:
  _ : Mirror, but is a no-op if the program flow is horizontal
  { : Shift stack left
  } : Shift stack right

Decrypt:
  b : Push 11 to stack
  ~ : Pop top of stack
  ! : Skip the next instruction

대체로 암호화 프로그램은 아무것도하지 않지만 암호 해독 프로그램은 다음 명령어를 건너 뜁니다. 그런 다음이를 확장 _{}! -> b~!$하여 암호화 프로그램 에서 임의의 문자를 건너 뛸 수 있습니다 .

이 외에도 프로그램의 나머지 대부분은 숫자를 밀고 그 숫자에 대한 작업을 수행 한 다음 팝하는 방법을 찾고 있습니다. 예를 들어, 하나의 유용한 구문은 ~~ -> ""암호화 프로그램에 두 개의 값을 표시하지만 암호 해독 프로그램에는 아무 것도 푸시하지 않습니다.


> <>, 149 바이트

전달되지 않은 명령어가 2D 언어로 효과적으로 주석 처리된다는 사실을 사용하는 덜 흥미로운 버전이 있습니다.

암호화 :

i68*:@-a*i@@-+i~v
4:v?)g31:;?(0:i:/8
(?v48*-+03g%48*+\*
_~\of0.   .1+1fo/
j*+:zq<6B99A6=qz6g
53Ji?C58/8;?r0?C5:
C?EiJ4r?<EFJ3;EtEg
:tAC5EK8l5tKK86t*i

해독 :

^+-~/5"V~^55" ^sk
)/k4}\(&/04|%/^/$-
|4k)-~" %(\y)-~ Q~
TsQd[%#ttt#& &[d$
_~ /of1+7..6+2fo+\
*(?^48*-$-04g%48*/
84:^?)g41:;?(0:i:\
/i68*:@-a*i@@-+i~^

두 프로그램은 84만큼 오프셋되며 위와 동일한 방식으로 입력됩니다. 첫 번째 명령 i은 암호화 프로그램에서 프로그램 흐름을 오른쪽 으로 (입력) 유지 ^하고, 해독 프로그램에서 프로그램 흐름을 위로 (루프 주변으로 돌아와 아래에서 다시) 재지 정하여 실행할 프로그램의 절반을 결정 합니다.

설명

암호화 프로그램의 관련 절반에 대해 (암호 해독 프로그램은 유사 함) :

i                       read first input digit as char
68*:@-a*                subtract 48 (ASCII "0") and multiply by 10, keeping another 48 on the stack
i                       read second input digit as char
@@-+                    subtract 48 and add to 10*(first digit), giving the offset
i~                      read in space and discard it

--- LOOP ---
:                       copy the offset
i:                      read input char
:0)?;                   check if less than 0 (i.e. EOF) and terminate if so
:13g)?v                 check if greater than ~ in cell (1,3) and drop down if so
48*(?v                  check if less than 32 and drop down if so
48*-+03g%48*+           calculate Caesar shift of the char, fetching 95 from (0,3)

of1+1.                  repeat loop
of0.                    repeat loop

코딩 툴

이것은 위의 나머지 게시물과 관련이 없지만 사용해야하기 때문에 게시 할 것이라고 생각했습니다.

for(var i=0;i<95;++i){var option=document.createElement("option");option.text=i;document.getElementById("offset").add(option)};function update(m){if(m==1)var code=document.getElementById("in").value;else var code=document.getElementById("out").value;var offset=parseInt(document.getElementById("offset").value);var output="";for(var i=0;i<code.length;i++){var n=code[i].charCodeAt(0);if(n<32||n>127)output+=code[i];else{var c=(n-32+offset*m)%95;output+=String.fromCharCode(c<0?c+95+32:c+32)}}if(m==1)document.getElementById("out").value=output;else document.getElementById("in").value=output};
<html><body><textarea id="in" onkeyup="update(1)" rows=5 style="width:100%"></textarea><textarea id="out" rows=5 style="width:100%" onkeyup="update(-1)"></textarea><select id="offset" onchange="update(1)"></select></body></html>


1

펄-131

명령 행 인수에서 입력을받습니다.

We;{for(split//,$ARGV[1]){print chr(((ord$_)-32+$ARGV[0])%95+32)}};q!LUXmYVROZttqi'8-<AvCnaVXOTZeINXmmmUXJiEnrxwri'8-<AuCnj~zpxwnc!

26만큼 바꾸면 다른 하나가 나타납니다.

q U6!*-B.+'$/IIF>[lapuKwC6+-$)/:}#-BBB*-~>yCGMLE>[lapuJwC?SOEMLC88U,;for(split//,$ARGV[1]){print chr(((ord$_)-32-$ARGV[0])%95+32)};

@Martin Büttner Woah, 공감 자! 실제로 않는 일을?
KSFT

그것은 내가 말할 수있는 한;)
Martin Ender
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.