César-Cypher-Mania

22

O César César é um código de substituição muito simples, em que cada letra é deslocada por um deslocamento fixo (repetindo Z a A). Da mesma forma, também podemos usar uma cifra de César para o conjunto de caracteres ASCII imprimíveis. Esses são os 95 caracteres dos pontos de código 0x20 a 0x7E. Para um determinado deslocamento d, mapeamos o ponto de código Cpara

(C - 32 + d) % 95 + 32

que muda todos os caracteres por a de circula de volta ~para o espaço. Caracteres fora desse intervalo (caracteres de controle como novas linhas, guias e caracteres fora do intervalo ASCII) não são afetados.

Você deve escrever dois programas ou funções (potencialmente em idiomas diferentes), que assumem um deslocamento de uma string. O primeiro programa deve retornar ou imprimir o código César da entrada. O segundo programa deve retornar ou imprimir o código de César inverso (ou seja, usando deslocamento -d). Você pode receber informações via STDIN, argumento de linha de comando ou argumento de função.

Para tornar as coisas mais interessantes, o segundo programa deve ser um código de César do primeiro programa. Ou seja, se você passar o código fonte do primeiro programa para si mesmo, para algum deslocamento diferente de zero d, a saída deverá ser o segundo programa.

Ambos os programas, bem como as cadeias de entrada, devem conter apenas caracteres ASCII imprimíveis, novas linhas e guias. Nenhum dos programas pode conter comentários ou ler seu próprio código-fonte, nome de arquivo ou ID do processo, direta ou indiretamente.

Isso é código de golfe, então a resposta mais curta (em bytes) vence. Como os dois programas devem ter o mesmo tamanho, você só precisa contar uma vez.

Martin Ender
fonte

Respostas:

12

Cjam, 40 38 37 bytes

Cifra para a frente:

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

Cifra Inversa:

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

e o segundo programa é o código do primeiro com diferença de 2


Como funciona

Eu vim com esta resposta sobre pura sorte enquanto testava as coisas.

Primeiro, as partes 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";

Agora vem a explicação da parte complicada.

As principais transformações são

<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

Então o primeiro programa é

 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 o segundo programa é

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

Entrada é como "<escaped string to be cyphered>" <difference>

Por exemplo:

"abcd" 4

e a saída do primeiro programa é

efgh

e do segundo programa é

]^_`

Experimente online aqui

Optimizer
fonte
não são esses 40 bytes? também ele dá um erro no interpretador on-line (algo em não ArrayLists sendo implementado)
Def
O @Deformyer corrigiu a contagem de bytes. Como você está dando a entrada?
Optimizer
Sim, meu mal, usei os argumentos na ordem errada.
Def
'"q ~' ~), 32> _ @ m <er" 9} o |% | '* 10 <]> k <cp}] "_-" 2' não funciona (java.lang.RuntimeException: inesperado})
Def
1
@Deformyer Você precisa escapar das aspas nessa cadeia de caracteres
Optimizer
7

Python 2, 147

Claramente, não pensei muito nisso, pois seria inútil em Python. Existem simplesmente dois programas separados, com o não utilizado envolto em uma string.

O deslocamento entre os dois programas é 39.

frente

Define a função Z que aceita uma string Unicode e um deslocamento.

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

Define a função que eu aceito uma string Unicode e um deslocamento.

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

Python 3-248 bytes

Meu objetivo era fazer isso como um liner Python. Objetivo de sucesso, mas agora não posso ser incomodado jogando golfe.

Criptografar:

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'

Descriptografar:

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

Editar: corrigido para não afetar caracteres fora do intervalo ASCII imprimível

O deslocamento de criptografar para descriptografar é 20. Use inserindo o deslocamento primeiro e depois a sequência, por exemplo

5
hello

Explicação

As seguintes transformações são a chave:

r -> '
' -> ;

O primeiro permite o uso de or, enquanto o segundo ignora uma string por ponto e vírgula.

Observe que "".__doc__[2]retorna a string r(retirada de str). Isso é necessário para evitar que a cadeia de caracteres entre aspas simples no programa de descriptografia tenha aspas dispersas no meio.

Sp3000
fonte
5

Ruby, 131 125 bytes

Aqui está minha própria submissão (que eu escrevi anteriormente como prova de conceito, mas consegui violar minhas próprias regras de alguma forma). Não estou reutilizando nenhum código entre os dois envios (quero que vocês superem isso, afinal), mas, em vez disso, consiste em duas linhas, uma das quais é transformada em uma string com sem sentido.

Cifra para frente:

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"

Cifra inversa:

"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

Ambos os trechos definem uma função (chamada Yno primeiro e Jno segundo), que pega um número inteiro e uma sequência e imprime a sequência transformada em STDOUT. O deslocamento entre as duas partes do código é 40.

Martin Ender
fonte
4

oOo CODE , 750 744 bytes, todo o código usado nos dois programas

Muito tempo, mas provavelmente é a ferramenta certa para fazer isso ...

Criptografar:

CcCcccccccccCcYcccCCCccCcCcCccccccCcCcccccCcCcccCcCccCccCcCCccccCcCccccCCcCccccCCccCccCcCCcccCCCcCccccCcCCcCCcCCcCcCcCccccCCccCccCccCccCccCccCccCccccccCCCcCccCccCCcCcCcccCCcCcccCcCCcCCcCcCCccCCcCCcCCcCCcCCcCCcCCcCCcCCcCCcCcccccccCccccCccccCCccccCCcCccCCcccCccccccccccCcCccCccCccCccCcCCccCCcccCcCcCccCCcccCCCcCcccccccccccccCCccCccCcCcCcccCCccccccccccCcCccccccCcCccccCCcCccCccCCcCccccccccccCCccCcCcCcccccCcCccCcCCCcCccCccCCcCccCccCccCcCcccccCcCcccCCCcCcCccccCcCccCCcCCcCCcCcCCcccCcCCcCCcCCcCCcCCcCCcCCcCCcCCcCcCcccCccCCcccccCcCcccCcccccCcccCcccCccCccCCcCcccccccccccccCCCcccCcCcCcccCcccCCCcCccCccCccCcCCccCccCcCCCcCccccCcCccccccccCcCccCccCcCCccccccCccccccccCcccCCccCccCccCCcCCcCCcCCcCcCcCcccccCcCCcCCcCCcCCcCCcCCcCCcCccCcCCcccCCccCcCcccCCcccCCCcCC

Descriptografar:

SsSsssssssssSsisssSSSssSsSsSssssssSsSsssssSsSsssSsSssSssSsSSssssSsSssssSSsSssssSSssSssSsSSsssSSSsSssssSsSSsSSsSSsSsSsSssssSSssSssSssSssSssSssSssSssssssSSSsSssSssSSsSsSsssSSsSsssSsSSsSSsSsSSssSSsSSsSSsSSsSSsSSsSSsSSsSSsSSsSsssssssSssssSssssSSssssSSsSssSSsssSssssssssssSsSssSssSssSssSsSSssSSsssSsSsSssSSsssSSSsSsssssssssssssSSssSssSsSsSsssSSssssssssssSsSssssssSsSssssSSsSssSssSSsSssssssssssSSssSsSsSsssssSsSssSsSSSsSssSssSSsSssSssSssSsSsssssSsSsssSSSsSsSssssSsSssSSsSSsSSsSsSSsssSsSSsSSsSSsSSsSSsSSsSSsSSsSSsSsSsssSssSSsssssSsSsssSsssssSsssSsssSssSssSSsSsssssssssssssSSSsssSsSsSsssSsssSSSsSssSssSssSsSSssSssSsSSSsSssssSsSssssssssSsSssSssSsSSssssssSssssssssSsssSSssSssSssSSsSSsSSsSSsSsSsSsssssSsSSsSSsSSsSSsSSsSSsSSsSssSsSSsssSSssSsSsssSSsssSSSsSS

Traduções de Brainfuck:

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

oOo CODE é uma variante Brainfuck, onde apenas o caso das letras é importante.

Ele pega o primeiro byte e usa seu código de caractere como d(então uma nova linha significa d = 10). O restante da entrada é a sequência. EOF é 0.

jimmy23013
fonte
4

GolfScript, 95 64 bytes, todo o código usado nos dois programas

Criptografar:

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

Descriptografar:

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

Formato de entrada:

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

Explicação

Descriptografar:

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.

Criptografar:

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

Javascript (ES7 Draft) - 167 165 bytes

Tomando emprestado o uso de strings do @feersum e o uso de ponto e vírgula do @MartinButtner;)

Criptografar:

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"

Descriptografar:

"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

Deslocamento para usar: 55

nderscore
fonte
1
Falha nas seqüências de caracteres vazias. É por isso que eu tive que colocar, or <empty string> and <function>e não apenas or <function>.
feersum
@feersum está corrigido agora ... e 2 bytes mais curto :)
nderscore
Hum, isso parece familiar. ;)
Martin Ender
@ MartinBüttner Eu não sei o que dizer ...;)
nderscore
2

> <> (Peixe) , 467 bytes

Criptografar:

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,

Descriptografar:

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/

Os dois programas são compensados ​​por 3 e recebem a entrada do formulário:

<2-digit offset> <text>

O deslocamento deve ter 2 dígitos, portanto, um deslocamento de 5 precisa ser inserido como 05.

Esse é um envio longo, mas quase todos os caracteres não preenchidos são usados ​​pelos dois programas . Há muito espaço em branco que definitivamente pode ser jogado fora, mas achei que o programa seria mais interessante dessa maneira.

Esta imagem destaca os caracteres usados ​​pelos dois programas.

Explicação

A principal construção que torna isso possível é _{} -> b~!, o que permite ignorar arbitrariamente os caracteres no programa de descriptografia. Quão?

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

Em suma, o programa de criptografia não faz nada, mas o programa de descriptografia ignora a próxima instrução. Isso pode ser estendido para _{}! -> b~!$, o que permite ignorar arbitrariamente os caracteres no programa de criptografia .

Além disso, a maior parte do restante do programa está empurrando números, realizando operações nesses números e encontrando maneiras de exibi-los. Por exemplo, uma construção útil é ~~ -> "", que exibe dois valores para o programa de criptografia, mas não empurra nada no programa de descriptografia.


> <>, 149 bytes

Aqui está a versão menos interessante, que usa o fato de que as instruções não passadas são efetivamente comentários em linguagens 2D.

Criptografar:

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

Descriptografar:

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

Os dois programas são deslocados em 84 e recebem a entrada da mesma maneira que acima. A primeira instrução decide qual metade do programa deve ser executada, imantendo (entrada) o fluxo do programa para a direita no programa de criptografia e ^redirecionando o fluxo do programa para cima (circulando e retornando de baixo) no programa de descriptografia.

Explicação

Para a metade relevante do programa de criptografia (o programa de descriptografia é semelhante):

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

Ferramenta de codificação

Isso não está relacionado ao restante da postagem acima, mas pensei em publicá-la porque preciso usá-la: 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
fonte
1

Perl - 131

Ele recebe entrada da linha de comando args.

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

Mudar para 26 dá o outro:

q U6!*-B.+'$/IIF>[lapuKwC6+-$)/:}#-BBB*-~>yCGMLE>[lapuJwC?SOEMLC88U,;for(split//,$ARGV[1]){print chr(((ord$_)-32-$ARGV[0])%95+32)};
KSFT
fonte
@Martin Büttner Woah, um voto positivo! Ele realmente faz o trabalho?
KSFT
ele faz tanto quanto eu posso dizer;) #
277 Martin Ender