Cesare-Cypher-Mania


22

Il Caesar Cypher è un cifrario di sostituzione molto semplice in cui ogni lettera viene spostata di un offset fisso (passando da Z ad A). Allo stesso modo, possiamo anche un cifrario di Cesare per l'insieme dei caratteri ASCII stampabili. Questi sono i 95 caratteri dai punti di codice da 0x20 a 0x7E. Per un dato offset d, mappiamo il punto di codice Ca

(C - 32 + d) % 95 + 32

che sposta tutti i personaggi di a de si sposta dallo ~spazio. I caratteri al di fuori di questo intervallo (controllano caratteri come newline, tab e caratteri al di fuori dell'intervallo ASCII) non sono interessati.

Devi scrivere due programmi o funzioni (potenzialmente in lingue diverse), che richiedono un offset de una stringa. Il primo programma dovrebbe restituire o stampare il cifrario Caesar dell'input. Il secondo programma dovrebbe restituire o stampare il cifrario Caesar inverso (cioè usando l'offset -d). È possibile accettare input tramite STDIN, argomento della riga di comando o argomento della funzione.

Per rendere le cose più interessanti, il secondo programma deve essere un cifrario di Cesare del primo programma. Cioè, se si passa il codice sorgente del primo programma a se stesso, per un offset diverso da zero d, l'output deve essere il secondo programma.

Entrambi i programmi, così come le stringhe di input, devono contenere solo caratteri ASCII, newline e tab stampabili. Nessun programma può contenere commenti o leggere il proprio codice sorgente, nome file o ID processo direttamente o indirettamente.

Questo è il golf del codice, quindi vince la risposta più breve (in byte). Poiché entrambi i programmi devono avere le stesse dimensioni, è necessario contarlo una sola volta.

Risposte:


12

Cjam, 40 38 37 byte

Forward Cypher:

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

Cypher inverso:

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

e il secondo programma è il codice del primo con differenza di 2


Come funziona

Mi è venuta in mente questa risposta per pura fortuna mentre provavo le cose.

Innanzitutto, le parti 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";

Ora arriva la spiegazione della parte difficile.

Le trasformazioni chiave sono

<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

Quindi il primo programma è

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

E il secondo programma è

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

L'input è come "<escaped string to be cyphered>" <difference>

Per esempio:

"abcd" 4

e l'output del primo programma è

efgh

e del secondo programma è

]^_`

Provalo online qui


non sono 40 byte? inoltre dà un errore nell'interprete online (qualcosa su Arraylists non implementato)
Def

@Deformyer ha corretto il conteggio dei byte. A cosa stai dando l'input?
Ottimizzatore

sì, mio ​​male, ho usato gli argomenti nell'ordine sbagliato.
Def

'"q ~' ~), 32> _ @ m <er" 9} o |% | '* 10 <]> k <cp}] "_-" 2' non funziona (java.lang.RuntimeException: Inaspettato})
Def

1
@Deformyer Devi sfuggire alle virgolette in quella stringa
Ottimizzatore

7

Python 2, 147

Chiaramente non ci ho pensato troppo, perché sarebbe inutile in Python. Esistono semplicemente due programmi separati, con quello inutilizzato racchiuso in una stringa.

L'offset tra i due programmi è 39.

Inoltrare

Definisce la funzione Z che accetta una stringa Unicode e un 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"

Inverso

Definisce la funzione Accetto una stringa Unicode e un 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

5

Python 3 - 248 byte

Il mio obiettivo era quello di farlo come un one-liner Python. Successo obiettivo, ma ora non posso preoccuparmi del golf.

Encrypt:

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'

Decrypt:

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

Modifica: risolto per non influire sui caratteri al di fuori dell'intervallo ASCII stampabile

L'offset da encrypt a decrypt è 20. Usare inserendo prima l'offset, quindi la stringa, ad es

5
hello

Spiegazione

Le seguenti trasformazioni sono la chiave:

r -> '
' -> ;

Il primo consente l'uso di or, mentre il secondo ignora una stringa con punti e virgola.

Si noti che "".__doc__[2]restituisce la stringa r(presa da str). Ciò è necessario per evitare che la stringa tra virgolette singole nel programma di decrittazione abbia virgolette al centro.


5

Rubino, 131 125 byte

Ecco il mio contributo (che avevo scritto in precedenza come prova del concetto, ma in qualche modo sono riuscito a violare le mie regole). Non sto riutilizzando alcun codice tra i due invii (voglio che voi ragazzi battiate questo, dopo tutto), ma invece è costituito da due righe, una delle quali viene trasformata in una stringa con parole incomprensibili.

Cifra diretta:

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 inverso:

"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

Entrambi i frammenti definiscono una funzione (chiamata Ynella prima e Jnella seconda), che accetta un numero intero e una stringa e stampa la stringa trasformata su STDOUT. L'offset tra i due pezzi di codice è 40.


4

oOo CODICE , 750 744 byte, tutto il codice utilizzato in entrambi i programmi

Troppo a lungo ma probabilmente è lo strumento giusto per farlo ...

Encrypt:

CcCcccccccccCcYcccCCCccCcCcCccccccCcCcccccCcCcccCcCccCccCcCCccccCcCccccCCcCccccCCccCccCcCCcccCCCcCccccCcCCcCCcCCcCcCcCccccCCccCccCccCccCccCccCccCccccccCCCcCccCccCCcCcCcccCCcCcccCcCCcCCcCcCCccCCcCCcCCcCCcCCcCCcCCcCCcCCcCCcCcccccccCccccCccccCCccccCCcCccCCcccCccccccccccCcCccCccCccCccCcCCccCCcccCcCcCccCCcccCCCcCcccccccccccccCCccCccCcCcCcccCCccccccccccCcCccccccCcCccccCCcCccCccCCcCccccccccccCCccCcCcCcccccCcCccCcCCCcCccCccCCcCccCccCccCcCcccccCcCcccCCCcCcCccccCcCccCCcCCcCCcCcCCcccCcCCcCCcCCcCCcCCcCCcCCcCCcCCcCcCcccCccCCcccccCcCcccCcccccCcccCcccCccCccCCcCcccccccccccccCCCcccCcCcCcccCcccCCCcCccCccCccCcCCccCccCcCCCcCccccCcCccccccccCcCccCccCcCCccccccCccccccccCcccCCccCccCccCCcCCcCCcCCcCcCcCcccccCcCCcCCcCCcCCcCCcCCcCCcCccCcCCcccCCccCcCcccCCcccCCCcCC

Decrypt:

SsSsssssssssSsisssSSSssSsSsSssssssSsSsssssSsSsssSsSssSssSsSSssssSsSssssSSsSssssSSssSssSsSSsssSSSsSssssSsSSsSSsSSsSsSsSssssSSssSssSssSssSssSssSssSssssssSSSsSssSssSSsSsSsssSSsSsssSsSSsSSsSsSSssSSsSSsSSsSSsSSsSSsSSsSSsSSsSSsSsssssssSssssSssssSSssssSSsSssSSsssSssssssssssSsSssSssSssSssSsSSssSSsssSsSsSssSSsssSSSsSsssssssssssssSSssSssSsSsSsssSSssssssssssSsSssssssSsSssssSSsSssSssSSsSssssssssssSSssSsSsSsssssSsSssSsSSSsSssSssSSsSssSssSssSsSsssssSsSsssSSSsSsSssssSsSssSSsSSsSSsSsSSsssSsSSsSSsSSsSSsSSsSSsSSsSSsSSsSsSsssSssSSsssssSsSsssSsssssSsssSsssSssSssSSsSsssssssssssssSSSsssSsSsSsssSsssSSSsSssSssSssSsSSssSssSsSSSsSssssSsSssssssssSsSssSssSsSSssssssSssssssssSsssSSssSssSssSSsSSsSSsSSsSsSsSsssssSsSSsSSsSSsSSsSSsSSsSSsSssSsSSsssSSssSsSsssSSsssSSSsSS

Traduzioni di Brainfuck:

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

oOo CODICE è una variante di Brainfuck in cui conta solo il caso delle lettere.

Prende il primo byte e usa il suo codice carattere come d(quindi una nuova riga significa d = 10). Il resto dell'input è la stringa. EOF è 0.


4

GolfScript, 95 64 byte, tutto il codice utilizzato in entrambi i programmi

Encrypt:

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

Decrypt:

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

Formato di input:

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

Spiegazione

Decrypt:

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.

Encrypt:

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 (ES7 Draft) - 167 165 byte

Prendendo in prestito dall'uso di stringhe di @feersum e dall'uso del punto e virgola di @MartinButtner;)

Encrypt:

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"

Decrypt:

"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 da usare: 55


1
Errore per stringhe vuote. Ecco perché ho dovuto mettere or <empty string> and <function>piuttosto che solo or <function>.
feersum

@feersum è stato risolto ora ... e 2 byte in meno :)
nderscore il

Hm, questo sembra familiare. ;)
Martin Ender il

@ MartinBüttner Non capisco cosa intendi ...;)
nderscore il

2

> <> (Pesce) , 467 byte

Encrypt:

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,

Decrypt:

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/

I due programmi sono sfalsati di 3 e prendono l'input del modulo:

<2-digit offset> <text>

L'offset deve essere di 2 cifre, pertanto è necessario immettere un offset di 5 come 05.

Questa è una lunga presentazione, ma quasi tutti i caratteri non di riempimento sono utilizzati da entrambi i programmi . C'è un sacco di spazio bianco che può sicuramente essere giocato a golf, ma ho pensato che il programma sarebbe stato più interessante in questo modo.

Questa immagine evidenzia i caratteri utilizzati da entrambi i programmi.

Spiegazione

Il costrutto principale che lo rende possibile è _{} -> b~!che consente di saltare arbitrariamente i caratteri nel programma di decrittazione. Come?

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

Tutto sommato, il programma di crittografia non fa nulla, ma il programma di decrittazione salta l'istruzione successiva. Questo può quindi essere esteso a _{}! -> b~!$, il che consente invece di saltare arbitrariamente i caratteri nel programma di crittografia .

A parte questo, la maggior parte del resto del programma sta spingendo i numeri, eseguendo operazioni su quei numeri e trovando il modo di farli apparire. Ad esempio, un costrutto utile è~~ -> "" , che apre due valori per il programma di crittografia, ma non inserisce nulla nel programma di decrittazione.


> <>, 149 byte

Ecco la versione meno interessante, che utilizza il fatto che le istruzioni non passate sono effettivamente commenti in linguaggi 2D.

Encrypt:

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

Decrypt:

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

I due programmi sono sfalsati di 84 e prendono l'input come sopra. La prima istruzione decide quale metà del programma eseguire, con i(input) che mantiene il flusso del programma verso destra nel programma di crittografia, e^ reindirizzando il flusso del programma verso l'alto (facendo il giro e ritornando dal basso) nel programma di decrittazione.

Spiegazione

Per la metà pertinente del programma di crittografia (il programma di decrittografia è simile):

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

Strumento di codifica

Questo non è correlato al resto del post sopra, ma ho pensato di postare questo perché ho bisogno di usarlo: 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

Prende input dagli arg della riga di comando.

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

Spostandolo di 26 si ottiene l'altro:

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, un voto! E 'in realtà fa il lavoro?
KSFT il

per quanto posso dire;)
Martin Ender,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.