Caesar-Cypher-Mania

22

Die Caesar-Chiffre ist eine sehr einfache Substitutions-Chiffre, bei der jeder Buchstabe um einen festen Versatz verschoben ist (Schleife um Z nach A). Ebenso können wir auch eine Caesar-Chiffre für den Satz druckbarer ASCII-Zeichen verwenden. Dies sind die 95 Zeichen von den Codepunkten 0x20 bis 0x7E. Für einen bestimmten Versatz ordnen dwir den Codepunkt Czu

(C - 32 + d) % 95 + 32

Das verschiebt alle Zeichen um a dund wandert von einem ~zum nächsten. Zeichen außerhalb dieses Bereichs (Steuerzeichen wie Zeilenumbrüche, Tabulatoren und Zeichen außerhalb des ASCII-Bereichs) sind nicht betroffen.

Sie müssen zwei Programme oder Funktionen (möglicherweise in verschiedenen Sprachen) schreiben, die einen Offset dund eine Zeichenfolge enthalten. Das erste Programm sollte den Caesar-Code der Eingabe zurückgeben oder ausdrucken. Das zweite Programm sollte die inverse Caesar-Chiffre zurückgeben oder drucken (dh Offset verwenden -d). Sie können Eingaben über STDIN, Befehlszeilenargument oder Funktionsargument vornehmen.

Um die Sache interessanter zu machen, muss das zweite Programm eine Cäsar-Chiffre des ersten Programms sein. Wenn Sie also den Quellcode des ersten Programms an sich selbst übergeben, dmuss die Ausgabe für einen Versatz ungleich Null das zweite Programm sein.

Beide Programme sowie die Eingabezeichenfolgen dürfen nur druckbare ASCII-Zeichen, Zeilenumbrüche und Tabulatoren enthalten. Kein Programm darf Kommentare enthalten oder seinen eigenen Quellcode, Dateinamen oder seine eigene Prozess-ID direkt oder indirekt lesen.

Dies ist Codegolf, daher gewinnt die kürzeste Antwort (in Bytes). Da beide Programme dieselbe Größe haben müssen, müssen Sie sie nur einmal zählen.

Martin Ender
quelle

Antworten:

12

Cjam, 40 38 37 Bytes

Forward Cypher:

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

Inverse Chiffre:

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

und das zweite Programm ist die Ziffer des ersten mit der Differenz von 2


Wie es funktioniert

Ich fand diese Antwort aus purem Glück, als ich die Dinge ausprobierte.

Zunächst die Cypher-Teile:

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

Nun folgt die Erklärung des schwierigen Teils.

Schlüsseltransformationen sind

<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

Das erste Programm ist also

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

Und das zweite Programm ist

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

Eingabe ist wie "<escaped string to be cyphered>" <difference>

Beispielsweise:

"abcd" 4

und die Ausgabe des ersten Programms ist

efgh

und des zweiten programms ist

]^_`

Probieren Sie es hier online aus

Optimierer
quelle
sind das nicht 40 bytes? es gibt auch einen Fehler im Online-Interpreter (etwas auf Arraylists wird nicht implementiert)
Def
@Deformyer hat die Byteanzahl korrigiert. Als was gibst du den Input?
Optimierer
yeah my bad, ich habe die Argumente in der falschen Reihenfolge verwendet.
Def
'"q ~' ~), 32> _ @ m <er" 9} o |% | '* 10 <]> k <cp}] "_-" 2' funktioniert nicht (java.lang.RuntimeException: Unerwartet})
Def
1
@ Deformyer Sie müssen die Anführungszeichen in diesem String
Optimizer
7

Python 2, 147

Offensichtlich habe ich nicht zu viel darüber nachgedacht, da es in Python sinnlos wäre. Es gibt einfach zwei separate Programme, wobei das nicht verwendete in einer Zeichenfolge eingeschlossen ist.

Der Versatz zwischen den beiden Programmen beträgt 39.

Nach vorne

Definiert die Funktion Z, die eine Unicode-Zeichenfolge und einen Offset akzeptiert.

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"

Inverse

Definiert die Funktion, die eine Unicode-Zeichenfolge und einen Offset akzeptiert.

"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
quelle
5

Python 3 - 248 Bytes

Mein Ziel war es, dies als Python-Einzeiler zu tun. Zielerfolg, aber jetzt kann ich mich nicht mehr ums Golfen kümmern.

Verschlüsseln:

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'

Entschlüsseln:

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

Bearbeiten: Behoben, dass Zeichen außerhalb des druckbaren ASCII-Bereichs nicht beeinflusst werden

Der Versatz vom Verschlüsseln zum Entschlüsseln beträgt 20. Verwenden Sie diesen Versatz, indem Sie zuerst den Versatz und dann die Zeichenfolge eingeben, z

5
hello

Erläuterung

Die folgenden Transformationen sind der Schlüssel:

r -> '
' -> ;

Die erste erlaubt die Verwendung von or, während die zweite Zeichenkette durch Semikolons ignoriert.

Beachten Sie, dass "".__doc__[2]die Zeichenfolge r(entnommen von str) zurückgegeben wird. Dies ist erforderlich, um zu verhindern, dass die Zeichenfolge in Anführungszeichen im Entschlüsselungsprogramm in der Mitte Streuungsanführungszeichen enthält.

Sp3000
quelle
5

Ruby, 131 125 Bytes

Hier ist meine eigene Vorlage (die ich zuvor als Proof of Concept geschrieben hatte, aber es gelang mir, irgendwie gegen meine eigenen Regeln zu verstoßen). Ich verwende keinen Code zwischen den beiden Einreichungen (ich möchte, dass ihr das immerhin besiegt), sondern es besteht aus zwei Zeilen, von denen eine in eine Zeichenfolge mit Kauderwelsch verwandelt wird.

Vorwärts-Chiffre:

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"

Inverse Chiffre:

"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

Beide Snippets definieren eine Funktion (die Yin der ersten und Jin der zweiten aufgerufen wird ), die eine Ganzzahl und eine Zeichenfolge verwendet und die transformierte Zeichenfolge in STDOUT ausgibt. Der Versatz zwischen den beiden Codeteilen beträgt 40.

Martin Ender
quelle
4

oOo CODE , 750 744 Byte, der gesamte Code wird in beiden Programmen verwendet

Zu lang, aber es ist wahrscheinlich das richtige Werkzeug, um das zu tun ...

Verschlüsseln:

CcCcccccccccCcYcccCCCccCcCcCccccccCcCcccccCcCcccCcCccCccCcCCccccCcCccccCCcCccccCCccCccCcCCcccCCCcCccccCcCCcCCcCCcCcCcCccccCCccCccCccCccCccCccCccCccccccCCCcCccCccCCcCcCcccCCcCcccCcCCcCCcCcCCccCCcCCcCCcCCcCCcCCcCCcCCcCCcCCcCcccccccCccccCccccCCccccCCcCccCCcccCccccccccccCcCccCccCccCccCcCCccCCcccCcCcCccCCcccCCCcCcccccccccccccCCccCccCcCcCcccCCccccccccccCcCccccccCcCccccCCcCccCccCCcCccccccccccCCccCcCcCcccccCcCccCcCCCcCccCccCCcCccCccCccCcCcccccCcCcccCCCcCcCccccCcCccCCcCCcCCcCcCCcccCcCCcCCcCCcCCcCCcCCcCCcCCcCCcCcCcccCccCCcccccCcCcccCcccccCcccCcccCccCccCCcCcccccccccccccCCCcccCcCcCcccCcccCCCcCccCccCccCcCCccCccCcCCCcCccccCcCccccccccCcCccCccCcCCccccccCccccccccCcccCCccCccCccCCcCCcCCcCCcCcCcCcccccCcCCcCCcCCcCCcCCcCCcCCcCccCcCCcccCCccCcCcccCCcccCCCcCC

Entschlüsseln:

SsSsssssssssSsisssSSSssSsSsSssssssSsSsssssSsSsssSsSssSssSsSSssssSsSssssSSsSssssSSssSssSsSSsssSSSsSssssSsSSsSSsSSsSsSsSssssSSssSssSssSssSssSssSssSssssssSSSsSssSssSSsSsSsssSSsSsssSsSSsSSsSsSSssSSsSSsSSsSSsSSsSSsSSsSSsSSsSSsSsssssssSssssSssssSSssssSSsSssSSsssSssssssssssSsSssSssSssSssSsSSssSSsssSsSsSssSSsssSSSsSsssssssssssssSSssSssSsSsSsssSSssssssssssSsSssssssSsSssssSSsSssSssSSsSssssssssssSSssSsSsSsssssSsSssSsSSSsSssSssSSsSssSssSssSsSsssssSsSsssSSSsSsSssssSsSssSSsSSsSSsSsSSsssSsSSsSSsSSsSSsSSsSSsSSsSSsSSsSsSsssSssSSsssssSsSsssSsssssSsssSsssSssSssSSsSsssssssssssssSSSsssSsSsSsssSsssSSSsSssSssSssSsSSssSssSsSSSsSssssSsSssssssssSsSssSssSsSSssssssSssssssssSsssSSssSssSssSSsSSsSSsSSsSsSsSsssssSsSSsSSsSSsSSsSSsSSsSSsSssSsSSsssSSssSsSsssSSsssSSSsSS

Brainfuck-Übersetzungen:

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

oOo CODE ist eine Brainfuck-Variante, bei der nur die Groß- und Kleinschreibung von Bedeutung ist.

Es nimmt das erste Byte und verwendet seinen Zeichencode als d(eine neue Zeile bedeutet also d = 10). Der Rest der Eingabe ist die Zeichenfolge. EOF ist 0.

jimmy23013
quelle
4

GolfScript, 95 64 Bytes, der gesamte Code wird in beiden Programmen verwendet

Verschlüsseln:

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

Entschlüsseln:

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

Eingabeformat:

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

Erläuterung

Entschlüsseln:

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.

Verschlüsseln:

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
quelle
3

Javascript (ES7-Entwurf) - 167 165 Bytes

Ausleihen von @feersums Verwendung von Strings und @MartinButtners Verwendung von Semikolon;)

Verschlüsseln:

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"

Entschlüsseln:

"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

Zu verwendender Versatz: 55

nderscore
quelle
1
Schlägt für leere Zeichenfolgen fehl. Deshalb musste ich or <empty string> and <function>eher als nur setzen or <function>.
Feersum
@feersum es ist jetzt behoben ... und 2 Bytes kürzer :)
nderscore
Hm, das kommt mir bekannt vor. ;)
Martin Ender
@ MartinBüttner Ich weiß nicht, was du meinst ...;)
nderscore
2

> <> (Fisch) , 467 Bytes

Verschlüsseln:

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,

Entschlüsseln:

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/

Die beiden Programme sind um 3 versetzt und nehmen die Eingabe der Form vor:

<2-digit offset> <text>

Der Versatz muss 2-stellig sein, daher muss ein Versatz von 5 als eingegeben werden 05.

Dies ist eine lange Übermittlung, aber fast alle Zeichen ohne Füllzeichen werden von beiden Programmen verwendet . Es gibt eine Menge Leerzeichen, die definitiv herausgolfen werden können, aber ich dachte, das Programm wäre auf diese Weise interessanter.

Dieses Bild hebt die Zeichen hervor, die von beiden Programmen verwendet werden.

Erläuterung

Das Hauptkonstrukt, das dies ermöglicht _{} -> b~!, ermöglicht das willkürliche Überspringen von Zeichen im Entschlüsselungsprogramm. Wie?

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

Alles in allem macht das Verschlüsselungsprogramm nichts, aber das Entschlüsselungsprogramm überspringt den nächsten Befehl. Dies kann dann erweitert werden _{}! -> b~!$, was stattdessen das willkürliche Überspringen von Zeichen im Verschlüsselungsprogramm ermöglicht .

Abgesehen davon drückt der größte Teil des Programms Zahlen, führt Operationen an diesen Zahlen durch und findet dann Möglichkeiten, sie zu platzieren. Ein nützliches Konstrukt ist beispielsweise ~~ -> "", bei dem zwei Werte für das Verschlüsselungsprogramm abgelegt werden, im Entschlüsselungsprogramm jedoch keine Pushs ausgeführt werden.


> <> 149 Bytes

Hier ist die weniger interessante Version, die die Tatsache ausnutzt, dass Anweisungen, die nicht durchgereicht werden, effektiv Kommentare in 2D-Sprachen sind.

Verschlüsseln:

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

Entschlüsseln:

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

Die beiden Programme sind um 84 versetzt und werden auf die gleiche Weise wie oben eingegeben. Der erste Befehl entscheidet, welche Hälfte des Programms ausgeführt werden soll, wobei der iProgrammfluss im Verschlüsselungsprogramm nach rechts (eingegeben) und der ^Programmfluss im Entschlüsselungsprogramm nach oben (in einer Schleife und von unten zurück) umgeleitet wird.

Erläuterung

Für die relevante Hälfte des Verschlüsselungsprogramms (Entschlüsselungsprogramm ist ähnlich):

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

Codierungswerkzeug

Dies hat nichts mit dem Rest des obigen Beitrags zu tun, aber ich dachte, ich würde das posten, weil ich es verwenden muss: 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
quelle
1

Perl - 131

Es nimmt Eingaben von Kommandozeilenargumenten entgegen.

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

Eine Verschiebung um 26 ergibt die andere:

q U6!*-B.+'$/IIF>[lapuKwC6+-$)/:}#-BBB*-~>yCGMLE>[lapuJwC?SOEMLC88U,;for(split//,$ARGV[1]){print chr(((ord$_)-32-$ARGV[0])%95+32)};
KSFT
quelle
@ Martin Büttner Woah, eine positive Bewertung! Es tatsächlich tut Arbeit?
KSFT
Soweit ich das beurteilen kann;)
Martin Ender