Caesar-Cypher-Mania


22

Các Caesar Cypher là một cypher thay rất đơn giản mà mỗi chữ cái được chuyển bởi một cố định bù đắp (looping xung quanh từ Z đến A). Tương tự, chúng ta cũng có thể là một cypher Caesar cho tập hợp các ký tự ASCII có thể in được. Đây là 95 ký tự từ các điểm mã 0x20 đến 0x7E. Đối với một độ lệch đã cho d, chúng tôi ánh xạ điểm mã Ctới

(C - 32 + d) % 95 + 32

mà dịch chuyển tất cả các ký tự bằng một dvà các vòng lặp từ ~không gian. Các ký tự ngoài phạm vi này (các ký tự điều khiển như dòng mới, tab và ký tự ngoài phạm vi ASCII) không bị ảnh hưởng.

Bạn sẽ viết hai chương trình hoặc hàm (có khả năng bằng các ngôn ngữ khác nhau), có phần bù dvà chuỗi. Chương trình đầu tiên sẽ trả lại hoặc in cypher Caesar của đầu vào. Chương trình thứ hai sẽ trả về hoặc in cypher nghịch đảo (nghĩa là sử dụng offset -d). Bạn có thể nhận đầu vào thông qua STDIN, đối số dòng lệnh hoặc đối số hàm.

Để làm cho mọi thứ thú vị hơn, chương trình thứ hai phải là một cypher của chương trình đầu tiên. Đó là, nếu bạn truyền mã nguồn của chương trình đầu tiên cho chính nó, đối với một số bù khác không d, đầu ra phải là chương trình thứ hai.

Cả hai chương trình, cũng như các chuỗi đầu vào, chỉ được chứa các ký tự, dòng mới và tab ASCII có thể in được. Không chương trình nào có thể chứa bất kỳ bình luận nào hoặc đọc mã nguồn, tên tệp hoặc ID tiến trình của nó trực tiếp hoặc gián tiếp.

Đây là mã golf, vì vậy câu trả lời ngắn nhất (tính bằng byte) sẽ thắng. Vì cả hai chương trình phải có cùng kích thước, bạn chỉ cần đếm nó một lần.

Câu trả lời:


12

Cjam, 40 38 37 byte

Chuyển tiếp Cypher:

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

Nghịch đảo Cypher:

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

và chương trình thứ hai là cypher của chương trình thứ nhất với sự khác biệt của 2


Làm thế nào nó hoạt động

Tôi đã đưa ra câu trả lời này về may mắn thuần túy trong khi thử nghiệm mọi thứ.

Đầu tiên, các phần Cypher:

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";

Bây giờ đến phần giải thích của phần khó khăn.

Các biến đổi chính là

<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

Vì vậy, chương trình đầu tiên là

 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";

Và chương trình thứ hai là

"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";

Đầu vào giống như "<escaped string to be cyphered>" <difference>

Ví dụ:

"abcd" 4

và đầu ra của chương trình đầu tiên là

efgh

và của chương trình thứ hai là

]^_`

Dùng thử trực tuyến tại đây


không phải là 40 byte? ngoài ra, nó còn báo lỗi trong trình thông dịch trực tuyến (một cái gì đó trên Arraylists không được triển khai)
Def

@Deformyer đã sửa số byte. Bạn đang cho đầu vào là gì?
Trình tối ưu hóa

yeah xấu của tôi, tôi đã sử dụng các đối số theo thứ tự sai.
Def

'"q ~' ~), 32> _ @ m <er" 9} o |% | '* 10 <]> k <cp}] "_-" 2' không hoạt động (java.lang.R nbException: Thật bất ngờ})
Def

1
@Deformyer Bạn phải thoát các trích dẫn trong chuỗi đó
Trình tối ưu hóa

7

Con trăn 2, 147

Rõ ràng tôi đã không nghĩ quá nhiều về điều này, vì nó sẽ là vô ích trong Python. Đơn giản chỉ có hai chương trình riêng biệt, với chương trình không sử dụng được gói trong một chuỗi.

Độ lệch giữa hai chương trình là 39.

Phía trước

Xác định hàm Z chấp nhận chuỗi Unicode và phần bù.

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"

Nghịch đảo

Xác định hàm tôi chấp nhận chuỗi Unicode và phần bù.

"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

Python 3 - 248 byte

Mục tiêu của tôi là làm điều này như một lớp lót Python. Mục tiêu thành công, nhưng bây giờ tôi không thể bị làm phiền khi chơi golf.

Mã hóa:

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'

Giải mã:

'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()));

Chỉnh sửa: Đã sửa để không ảnh hưởng đến ký tự bên ngoài phạm vi ASCII có thể in

Offset từ mã hóa để giải mã là 20. Sử dụng bằng cách nhập offset trước, sau đó là chuỗi, vd

5
hello

Giải trình

Các biến đổi sau đây là chìa khóa:

r -> '
' -> ;

Cái đầu tiên cho phép sử dụng or, trong khi cái thứ hai bỏ qua một chuỗi bằng dấu chấm phẩy.

Lưu ý rằng "".__doc__[2]trả về chuỗi r(lấy từ str). Điều này là cần thiết để ngăn chặn chuỗi trích dẫn duy nhất trong chương trình giải mã có dấu ngoặc kép ở giữa.


5

Ruby, 131 125 byte

Đây là bài nộp của riêng tôi (mà tôi đã viết trước đó như một bằng chứng về khái niệm, nhưng tôi đã vi phạm các quy tắc của riêng mình bằng cách nào đó). Tôi không sử dụng lại bất kỳ mã nào giữa hai lần gửi (tôi muốn các bạn đánh bại điều này, sau tất cả), nhưng thay vào đó, nó bao gồm hai dòng, một trong số đó được biến thành một chuỗi với sự vô nghĩa.

Chuyển tiếp cypher:

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"

Nghịch đảo cypher:

"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

Cả hai đoạn mã đều xác định một hàm (được gọi Ytrong hàm đầu tiên và Jtrong đoạn thứ hai), lấy một số nguyên và một chuỗi và in chuỗi đã chuyển đổi thành STDOUT. Phần bù giữa hai đoạn mã là 40.


4

oOo CODE , 750 744 byte, tất cả mã được sử dụng trong cả hai chương trình

Quá dài nhưng có lẽ đó là công cụ phù hợp để làm điều đó ...

Mã hóa:

CcCcccccccccCcYcccCCCccCcCcCccccccCcCcccccCcCcccCcCccCccCcCCccccCcCccccCCcCccccCCccCccCcCCcccCCCcCccccCcCCcCCcCCcCcCcCccccCCccCccCccCccCccCccCccCccccccCCCcCccCccCCcCcCcccCCcCcccCcCCcCCcCcCCccCCcCCcCCcCCcCCcCCcCCcCCcCCcCCcCcccccccCccccCccccCCccccCCcCccCCcccCccccccccccCcCccCccCccCccCcCCccCCcccCcCcCccCCcccCCCcCcccccccccccccCCccCccCcCcCcccCCccccccccccCcCccccccCcCccccCCcCccCccCCcCccccccccccCCccCcCcCcccccCcCccCcCCCcCccCccCCcCccCccCccCcCcccccCcCcccCCCcCcCccccCcCccCCcCCcCCcCcCCcccCcCCcCCcCCcCCcCCcCCcCCcCCcCCcCcCcccCccCCcccccCcCcccCcccccCcccCcccCccCccCCcCcccccccccccccCCCcccCcCcCcccCcccCCCcCccCccCccCcCCccCccCcCCCcCccccCcCccccccccCcCccCccCcCCccccccCccccccccCcccCCccCccCccCCcCCcCCcCCcCcCcCcccccCcCCcCCcCCcCCcCCcCCcCCcCccCcCCcccCCccCcCcccCCcccCCCcCC

Giải mã:

SsSsssssssssSsisssSSSssSsSsSssssssSsSsssssSsSsssSsSssSssSsSSssssSsSssssSSsSssssSSssSssSsSSsssSSSsSssssSsSSsSSsSSsSsSsSssssSSssSssSssSssSssSssSssSssssssSSSsSssSssSSsSsSsssSSsSsssSsSSsSSsSsSSssSSsSSsSSsSSsSSsSSsSSsSSsSSsSSsSsssssssSssssSssssSSssssSSsSssSSsssSssssssssssSsSssSssSssSssSsSSssSSsssSsSsSssSSsssSSSsSsssssssssssssSSssSssSsSsSsssSSssssssssssSsSssssssSsSssssSSsSssSssSSsSssssssssssSSssSsSsSsssssSsSssSsSSSsSssSssSSsSssSssSssSsSsssssSsSsssSSSsSsSssssSsSssSSsSSsSSsSsSSsssSsSSsSSsSSsSSsSSsSSsSSsSSsSSsSsSsssSssSSsssssSsSsssSsssssSsssSsssSssSssSSsSsssssssssssssSSSsssSsSsSsssSsssSSSsSssSssSssSsSSssSssSsSSSsSssssSsSssssssssSsSssSssSsSSssssssSssssssssSsssSSssSssSssSSsSSsSSsSSsSsSsSsssssSsSSsSSsSSsSSsSSsSSsSSsSssSsSSsssSSssSsSsssSSsssSSSsSS

Bản dịch Brainfuck:

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

oOo CODE là một biến thể Brainfuck trong đó chỉ có trường hợp chữ cái quan trọng.

Nó lấy byte đầu tiên và sử dụng mã ký tự của nó là d(vì vậy một dòng mới có nghĩa là d = 10). Phần còn lại của đầu vào là chuỗi. EOF là 0.


4

GolfScript, 95 64 byte, tất cả mã được sử dụng trong cả hai chương trình

Mã hóa:

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

Giải mã:

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

Định dạng đầu vào:

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

Giải trình

Giải mã:

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.

Mã hóa:

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

Javascript (Bản nháp ES7) - 167 165 byte

Mượn từ việc sử dụng chuỗi của @feersum và việc sử dụng dấu chấm phẩy của @MartinButtner;)

Mã hóa:

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"

Giải mã:

"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

Bù đắp để sử dụng: 55


1
Thất bại cho chuỗi trống. Đó là lý do tại sao tôi phải đặt or <empty string> and <function>chứ không phải chỉ or <function>.
frageum

@feersum hiện đã được sửa ... và ngắn hơn 2 byte :)
nderscore

Hừm, cái này có vẻ quen. ;)
Martin Ender

@ MartinBüttner Tôi không biết ý của bạn là gì ...;)
nderscore

2

> <> (Cá) , 467 byte

Mã hóa:

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,

Giải mã:

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/

Hai chương trình được bù 3, và chúng lấy đầu vào của mẫu:

<2-digit offset> <text>

Phần bù phải có 2 chữ số, do đó, phần bù 5 cần được nhập là 05.

Đây là một bài nộp dài, nhưng gần như tất cả các ký tự không điền được sử dụng bởi cả hai chương trình . Có rất nhiều khoảng trắng chắc chắn có thể được đánh gôn, nhưng tôi nghĩ chương trình này sẽ thú vị hơn theo cách này.

Hình ảnh này làm nổi bật các ký tự được sử dụng bởi cả hai chương trình.

Giải trình

Cấu trúc chính làm cho điều này có thể là _{} -> b~!, cho phép bỏ qua các ký tự tùy ý trong chương trình giải mã. Làm sao?

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

Nói chung, chương trình mã hóa không làm gì cả, nhưng chương trình giải mã bỏ qua hướng dẫn tiếp theo. Điều này sau đó có thể được mở rộng _{}! -> b~!$, cho phép bỏ qua các ký tự tùy ý trong chương trình mã hóa thay thế.

Bên cạnh đó, hầu hết các phần còn lại của chương trình đang đẩy số, thực hiện các thao tác trên những số đó sau đó tìm cách bật chúng. Ví dụ, một cấu trúc hữu ích là ~~ -> "", bật hai giá trị cho chương trình mã hóa, nhưng không đẩy được gì trong chương trình giải mã.


> <>, 149 byte

Đây là phiên bản ít thú vị hơn, sử dụng thực tế là các hướng dẫn không được thông qua là nhận xét hiệu quả bằng các ngôn ngữ 2D.

Mã hóa:

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

Giải mã:

^+-~/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~^

Hai chương trình được bù bằng 84 và lấy đầu vào giống như trên. Lệnh đầu tiên quyết định một nửa chương trình sẽ thực hiện, với i(đầu vào) duy trì luồng chương trình ngay trong chương trình mã hóa và ^chuyển hướng chương trình đi lên (vòng quanh và quay lại từ dưới) trong chương trình giải mã.

Giải trình

Đối với một nửa có liên quan của chương trình mã hóa (chương trình giải mã tương tự):

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

Công cụ mã hóa

Điều này không liên quan đến phần còn lại của bài viết ở trên, nhưng tôi nghĩ tôi sẽ đăng bài này vì tôi cần sử dụng nó: P

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

Perl - 131

Nó nhận đầu vào từ dòng lệnh args.

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

Thay đổi nó bằng 26 cung cấp cho người khác:

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, một upvote! Nó thực sự làm việc?
KSFT

nó làm như tôi có thể nói;)
Martin Ender
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.