Caesar-Cypher-Mania

22

The Caesar Cypher adalah nol substitusi yang sangat sederhana di mana setiap huruf digeser oleh offset tetap (looping sekitar Z ke A). Demikian pula, kita juga bisa menggunakan cypher Caesar untuk set karakter ASCII yang dapat dicetak. Ini adalah 95 karakter dari titik kode 0x20 hingga 0x7E. Untuk offset yang diberikan d, kami memetakan titik kode Cke

(C - 32 + d) % 95 + 32

yang menggeser semua karakter dengan a ddan loop dari ~ke luar angkasa. Karakter di luar rentang ini (karakter kontrol seperti baris baru, tab, dan karakter di luar rentang ASCII) tidak terpengaruh.

Anda harus menulis dua program atau fungsi (berpotensi dalam bahasa yang berbeda), yang mengambil offset ddan string. Program pertama harus mengembalikan atau mencetak kode sandi input. Program kedua harus mengembalikan atau mencetak terbalik Caesar (yaitu menggunakan offset -d). Anda dapat mengambil input melalui STDIN, argumen baris perintah atau argumen fungsi.

Untuk membuat segalanya lebih menarik, program kedua haruslah kode sandi Caesar dari program pertama. Yaitu, jika Anda meneruskan kode sumber dari program pertama ke dirinya sendiri, untuk beberapa offset non-nold , output harus menjadi program kedua.

Kedua program, serta string input, harus hanya berisi karakter, baris dan tab ASCII yang dapat dicetak. Tidak ada program yang dapat berisi komentar atau membaca kode sumbernya sendiri, nama file atau ID proses secara langsung atau tidak langsung.

Ini adalah kode golf, jadi jawaban tersingkat (dalam byte) menang. Karena kedua program harus memiliki ukuran yang sama, Anda hanya perlu menghitungnya sekali.

Martin Ender
sumber

Jawaban:

12

Cjam, 40 38 37 byte

Teruskan Cypher:

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

Invers Cypher:

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

dan program kedua adalah cypher yang pertama dengan perbedaan 2


Bagaimana itu bekerja

Saya datang dengan jawaban ini pada keberuntungan murni saat menguji semuanya.

Pertama, bagian-bagian 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";

Sekarang tiba penjelasan dari bagian yang sulit.

Transformasi kunci adalah

<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

Jadi program pertama adalah

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

Dan program kedua adalah

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

Inputnya seperti "<escaped string to be cyphered>" <difference>

Sebagai contoh:

"abcd" 4

dan output dari program pertama adalah

efgh

dan program kedua adalah

]^_`

Cobalah online di sini

Pengoptimal
sumber
bukankah itu 40 byte? juga memberikan kesalahan pada penerjemah online (sesuatu pada Arraylists tidak diimplementasikan)
Def
@Deformyer mengoreksi jumlah byte. Apa yang Anda beri input?
Pengoptimal
ya salahku, saya menggunakan argumen dalam urutan yang salah.
Def
'"q ~' ~), 32> _ @ m <er" 9} o |% | '* 10 <]> k <cp}] "_-" 2' tidak berfungsi (java.lang.RuntimeException: Tidak terduga})
Def
1
@Deformyer Anda harus menghindari tanda kutip dalam string itu
Pengoptimal
7

Python 2, 147

Jelas saya tidak berpikir terlalu keras tentang ini, karena akan sia-sia dengan Python. Hanya ada dua program yang terpisah, dengan yang tidak digunakan terbungkus dalam sebuah string.

Offset antara kedua program adalah 39.

Meneruskan

Menentukan fungsi Z menerima string Unicode dan offset.

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"

Terbalik

Menentukan fungsi Saya menerima string Unicode dan offset.

"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
feersum
sumber
5

Python 3 - 248 byte

Tujuan saya adalah melakukan ini sebagai satu-baris Python. Gol sukses, tapi sekarang saya tidak bisa diganggu golf.

Enkripsi:

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'

Dekripsi:

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

Sunting: Diperbaiki untuk tidak memengaruhi karakter di luar rentang ASCII yang dapat dicetak

Offset dari enkripsi ke dekripsi adalah 20. Gunakan dengan memasukkan offset terlebih dahulu, kemudian string, misalnya

5
hello

Penjelasan

Transformasi berikut adalah kuncinya:

r -> '
' -> ;

Yang pertama memungkinkan penggunaan or, sedangkan yang kedua mengabaikan string dengan titik koma.

Perhatikan bahwa "".__doc__[2]mengembalikan string r(diambil dari str). Ini diperlukan untuk mencegah string yang dikutip tunggal dalam program dekripsi dari memiliki tanda kutip di tengah.

Sp3000
sumber
5

Ruby, 131 125 byte

Ini pengajuan saya sendiri (yang saya tulis sebelumnya sebagai bukti konsep, tetapi saya entah bagaimana berhasil melanggar aturan saya sendiri). Saya tidak menggunakan kembali kode apa pun di antara dua pengiriman (Saya ingin kalian mengalahkan ini, setelah semua), tetapi itu terdiri dari dua baris, salah satunya diubah menjadi string dengan omong kosong.

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

Cypher terbalik:

"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

Kedua snippet mendefinisikan suatu fungsi (dipanggil Ydi yang pertama, dan Jyang kedua), yang mengambil integer dan string dan mencetak string yang diubah ke STDOUT. Offset antara dua bagian kode adalah 40.

Martin Ender
sumber
4

oOo CODE , 750 744 bytes, semua kode yang digunakan di kedua program

Terlalu lama tapi itu mungkin alat yang tepat untuk melakukan itu ...

Enkripsi:

CcCcccccccccCcYcccCCCccCcCcCccccccCcCcccccCcCcccCcCccCccCcCCccccCcCccccCCcCccccCCccCccCcCCcccCCCcCccccCcCCcCCcCCcCcCcCccccCCccCccCccCccCccCccCccCccccccCCCcCccCccCCcCcCcccCCcCcccCcCCcCCcCcCCccCCcCCcCCcCCcCCcCCcCCcCCcCCcCCcCcccccccCccccCccccCCccccCCcCccCCcccCccccccccccCcCccCccCccCccCcCCccCCcccCcCcCccCCcccCCCcCcccccccccccccCCccCccCcCcCcccCCccccccccccCcCccccccCcCccccCCcCccCccCCcCccccccccccCCccCcCcCcccccCcCccCcCCCcCccCccCCcCccCccCccCcCcccccCcCcccCCCcCcCccccCcCccCCcCCcCCcCcCCcccCcCCcCCcCCcCCcCCcCCcCCcCCcCCcCcCcccCccCCcccccCcCcccCcccccCcccCcccCccCccCCcCcccccccccccccCCCcccCcCcCcccCcccCCCcCccCccCccCcCCccCccCcCCCcCccccCcCccccccccCcCccCccCcCCccccccCccccccccCcccCCccCccCccCCcCCcCCcCCcCcCcCcccccCcCCcCCcCCcCCcCCcCCcCCcCccCcCCcccCCccCcCcccCCcccCCCcCC

Dekripsi:

SsSsssssssssSsisssSSSssSsSsSssssssSsSsssssSsSsssSsSssSssSsSSssssSsSssssSSsSssssSSssSssSsSSsssSSSsSssssSsSSsSSsSSsSsSsSssssSSssSssSssSssSssSssSssSssssssSSSsSssSssSSsSsSsssSSsSsssSsSSsSSsSsSSssSSsSSsSSsSSsSSsSSsSSsSSsSSsSSsSsssssssSssssSssssSSssssSSsSssSSsssSssssssssssSsSssSssSssSssSsSSssSSsssSsSsSssSSsssSSSsSsssssssssssssSSssSssSsSsSsssSSssssssssssSsSssssssSsSssssSSsSssSssSSsSssssssssssSSssSsSsSsssssSsSssSsSSSsSssSssSSsSssSssSssSsSsssssSsSsssSSSsSsSssssSsSssSSsSSsSSsSsSSsssSsSSsSSsSSsSSsSSsSSsSSsSSsSSsSsSsssSssSSsssssSsSsssSsssssSsssSsssSssSssSSsSsssssssssssssSSSsssSsSsSsssSsssSSSsSssSssSssSsSSssSssSsSSSsSssssSsSssssssssSsSssSssSsSSssssssSssssssssSsssSSssSssSssSSsSSsSSsSSsSsSsSsssssSsSSsSSsSSsSSsSSsSSsSSsSssSsSSsssSSssSsSsssSSsssSSSsSS

Terjemahan Brainfuck:

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

oOo CODE adalah varian Brainfuck di mana hanya masalah huruf yang penting.

Dibutuhkan byte pertama dan menggunakan kode karakternya d(jadi baris baru berarti d = 10). Input lainnya adalah string. EOF adalah 0.

jimmy23013
sumber
4

GolfScript, 95 64 byte, semua kode digunakan di kedua program

Enkripsi:

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

Dekripsi:

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

Masukkan format:

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

Penjelasan

Dekripsi:

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.

Enkripsi:

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.
jimmy23013
sumber
3

Javascript (ES7 Draft) - 167 165 byte

Meminjam dari penggunaan senar @feersum dan penggunaan titik koma @MartinButtner;)

Enkripsi:

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"

Dekripsi:

"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

Offset untuk digunakan: 55

nderscore
sumber
1
Gagal untuk string kosong. Itu sebabnya saya harus meletakkan or <empty string> and <function>bukan hanya or <function>.
feersum
@feersum sudah diperbaiki sekarang ... dan 2 byte lebih pendek :)
nderscore
Hm, ini terlihat familier. ;)
Martin Ender
@ MartinBüttner Saya tidak tahu maksud Anda ...;)
nderscore
2

> <> (Ikan) , 467 byte

Enkripsi:

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,

Dekripsi:

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/

Kedua program diimbangi oleh 3, dan mereka mengambil input dari formulir:

<2-digit offset> <text>

Offset harus 2 digit, sehingga offset 5 harus dimasukkan sebagai 05.

Ini adalah pengiriman yang panjang, tetapi hampir semua karakter non-filler digunakan oleh kedua program . Ada banyak ruang putih yang pasti bisa bermain golf, tapi saya pikir programnya akan lebih menarik dengan cara ini.

Gambar ini menyoroti karakter yang digunakan oleh kedua program.

Penjelasan

Konstruk utama yang memungkinkan ini adalah _{} -> b~!, yang memungkinkan melewatkan karakter acak dalam program dekripsi. Bagaimana?

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

Secara keseluruhan, program enkripsi tidak melakukan apa-apa, tetapi program dekripsi melewatkan instruksi selanjutnya. Ini kemudian dapat diperluas ke _{}! -> b~!$, yang memungkinkan melewatkan karakter acak dalam enkripsi program sebagai gantinya.

Selain itu, sebagian besar sisa program mendorong angka, melakukan operasi pada angka-angka itu kemudian menemukan cara untuk menghapusnya. Misalnya, satu konstruk yang bermanfaat adalah ~~ -> "", yang mengeluarkan dua nilai untuk program enkripsi, tetapi tidak mendorong apa pun dalam program dekripsi.


> <>, 149 byte

Inilah versi yang kurang menarik, yang menggunakan fakta bahwa instruksi yang tidak dilewati adalah komentar efektif dalam bahasa 2D.

Enkripsi:

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

Dekripsi:

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

Kedua program diimbangi oleh 84, dan mengambil input dengan cara yang sama seperti di atas. Instruksi pertama memutuskan setengah dari program yang akan dijalankan, dengan i(input) mempertahankan aliran program ke kanan dalam program enkripsi, dan^ mengarahkan aliran program ke atas (berputar-putar dan kembali dari bawah) dalam program dekripsi.

Penjelasan

Untuk separuh yang relevan dari program enkripsi (program dekripsi serupa):

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

Alat pengkodean

Ini tidak terkait dengan sisa posting di atas, tetapi saya pikir saya akan memposting ini karena saya perlu menggunakannya: 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>

Sp3000
sumber
1

Perl - 131

Dibutuhkan input dari baris perintah args.

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

Menggesernya dengan 26 memberi yang lain:

q U6!*-B.+'$/IIF>[lapuKwC6+-$)/:}#-BBB*-~>yCGMLE>[lapuJwC?SOEMLC88U,;for(split//,$ARGV[1]){print chr(((ord$_)-32-$ARGV[0])%95+32)};
KSFT
sumber
@Martin Büttner Woah, upvote! Ini benar - benar bekerja?
KSFT
sejauh yang saya tahu;)
Martin Ender