Цезарь-Cypher-Mania

22

Цезаря Шифр является очень простой шифр подстановки , где каждая буква сдвигается на фиксированное смещение (зацикливание вокруг Z до А). Точно так же мы можем также использовать шифр Цезаря для набора печатных символов ASCII. Это 95 символов из кодовых точек от 0x20 до 0x7E. Для данного смещения dмы отображаем кодовую точкуC в

(C - 32 + d) % 95 + 32

который сдвигает все символы на d и зацикливается ~на пространстве. Символы вне этого диапазона (управляющие символы, такие как переводы строки, символы табуляции и символы вне диапазона ASCII) не затрагиваются.

Вы должны написать две программы или функции (возможно, на разных языках), которые принимают смещение dи строку. Первая программа должна вернуть или напечатать Цезарь-шифр ввода. Вторая программа должна вернуть или распечатать обратный шифр Цезаря (то есть, используя смещение -d). Вы можете получить ввод через STDIN, аргумент командной строки или аргумент функции.

Чтобы сделать вещи более интересными, вторая программа должна быть шифром Цезаря первой программы. То есть, если вы передадите исходный код первой программы самому себе, для некоторого ненулевого смещения d, на выходе должна быть вторая программа.

Обе программы, а также строки ввода должны содержать только печатные символы ASCII, символы новой строки и вкладки. Ни одна из программ не может содержать комментарии или читать свой собственный исходный код, имя файла или идентификатор процесса прямо или косвенно.

Это код гольф, поэтому самый короткий ответ (в байтах) выигрывает. Поскольку обе программы должны иметь одинаковый размер, вам нужно только посчитать его один раз.

Мартин Эндер
источник

Ответы:

12

Cjam, 40 38 37 байт

Форвард Сайфер:

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

Обратный шифр:

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

а вторая программа является шифром первой с разницей 2


Как это работает

Я придумал этот ответ на чистую удачу, когда проверял.

Во-первых, части 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";

Теперь приходит объяснение хитрой части.

Ключевые преобразования

<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

Итак, первая программа

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

И вторая программа

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

Ввод как "<escaped string to be cyphered>" <difference>

Например:

"abcd" 4

и вывод первой программы

efgh

и второй программы

]^_`

Попробуйте онлайн здесь

оптимизатор
источник
Разве это не 40 байтов? также он выдает ошибку в онлайн-переводчике (что-то на Arraylists не выполняется)
Def
@Deformyer исправил количество байтов. Что вы даете вход как?
Оптимизатор
да, плохо, я использовал аргументы в неправильном порядке.
Def
'"q ~' ~), 32> _ @ m <er" 9} o |% | '* 10 <]> k <cp}] "_-" 2' не работает (java.lang.RuntimeException: Неожиданно})
Def
1
@Deformyer Вы должны избежать кавычек в этой строке
Оптимизатор
7

Python 2, 147

Очевидно, я не слишком задумывался об этом, так как это было бы бесполезно в Python. Есть просто две отдельные программы, неиспользованная из которых заключена в строку.

Смещение между двумя программами составляет 39.

Вперед

Определяет функцию Z, принимающую строку Unicode и смещение.

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"

обратный

Определяет функцию я принимаю строку Юникод и смещение.

"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
источник
5

Python 3 - 248 байт

Моей целью было сделать это как однострочник Python. Гол успеха, но теперь я не могу быть обеспокоен игрой в гольф.

Шифрование:

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'

Расшифровать:

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

Редактировать: Исправлено, чтобы не влиять на символы вне диапазона ASCII для печати

Смещение от шифрования к дешифрованию равно 20. Используйте, сначала введя смещение, затем строку, например

5
hello

объяснение

Следующие преобразования являются ключевыми:

r -> '
' -> ;

Первый позволяет использовать or, а второй игнорирует строку через точку с запятой.

Обратите внимание, что "".__doc__[2]возвращает строку r(взято из str). Это необходимо для того, чтобы строка с одинарными кавычками в программе расшифровки не имела случайных кавычек в середине.

Sp3000
источник
5

Рубин, 131 125 байт

Вот мое собственное представление (которое я написал ранее в качестве доказательства концепции, но мне удалось как-то нарушить мои собственные правила). Я не использую какой-либо код между двумя представлениями (в конце концов, я хочу, чтобы вы, ребята, побили это), но вместо этого он состоит из двух строк, одна из которых превращается в строку с бредом.

Вперед шифр:

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"

Обратный шифр:

"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

Оба фрагмента определяют функцию (вызываемую Yв первом и Jво втором), которая принимает целое число и строку и печатает преобразованную строку в STDOUT. Смещение между двумя частями кода составляет 40.

Мартин Эндер
источник
4

ооо код , 750 744 байта, весь код используется в обеих программах

Слишком долго, но это, вероятно, правильный инструмент для этого ...

Шифрование:

CcCcccccccccCcYcccCCCccCcCcCccccccCcCcccccCcCcccCcCccCccCcCCccccCcCccccCCcCccccCCccCccCcCCcccCCCcCccccCcCCcCCcCCcCcCcCccccCCccCccCccCccCccCccCccCccccccCCCcCccCccCCcCcCcccCCcCcccCcCCcCCcCcCCccCCcCCcCCcCCcCCcCCcCCcCCcCCcCCcCcccccccCccccCccccCCccccCCcCccCCcccCccccccccccCcCccCccCccCccCcCCccCCcccCcCcCccCCcccCCCcCcccccccccccccCCccCccCcCcCcccCCccccccccccCcCccccccCcCccccCCcCccCccCCcCccccccccccCCccCcCcCcccccCcCccCcCCCcCccCccCCcCccCccCccCcCcccccCcCcccCCCcCcCccccCcCccCCcCCcCCcCcCCcccCcCCcCCcCCcCCcCCcCCcCCcCCcCCcCcCcccCccCCcccccCcCcccCcccccCcccCcccCccCccCCcCcccccccccccccCCCcccCcCcCcccCcccCCCcCccCccCccCcCCccCccCcCCCcCccccCcCccccccccCcCccCccCcCCccccccCccccccccCcccCCccCccCccCCcCCcCCcCCcCcCcCcccccCcCCcCCcCCcCCcCCcCCcCCcCccCcCCcccCCccCcCcccCCcccCCCcCC

Расшифровать:

SsSsssssssssSsisssSSSssSsSsSssssssSsSsssssSsSsssSsSssSssSsSSssssSsSssssSSsSssssSSssSssSsSSsssSSSsSssssSsSSsSSsSSsSsSsSssssSSssSssSssSssSssSssSssSssssssSSSsSssSssSSsSsSsssSSsSsssSsSSsSSsSsSSssSSsSSsSSsSSsSSsSSsSSsSSsSSsSSsSsssssssSssssSssssSSssssSSsSssSSsssSssssssssssSsSssSssSssSssSsSSssSSsssSsSsSssSSsssSSSsSsssssssssssssSSssSssSsSsSsssSSssssssssssSsSssssssSsSssssSSsSssSssSSsSssssssssssSSssSsSsSsssssSsSssSsSSSsSssSssSSsSssSssSssSsSsssssSsSsssSSSsSsSssssSsSssSSsSSsSSsSsSSsssSsSSsSSsSSsSSsSSsSSsSSsSSsSSsSsSsssSssSSsssssSsSsssSsssssSsssSsssSssSssSSsSsssssssssssssSSSsssSsSsSsssSsssSSSsSssSssSssSsSSssSssSsSSSsSssssSsSssssssssSsSssSssSsSSssssssSssssssssSsssSSssSssSssSSsSSsSSsSSsSsSsSsssssSsSSsSSsSSsSSsSSsSSsSSsSssSsSSsssSSssSsSsssSSsssSSSsSS

Brainfuck переводы:

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

oOo CODE - это вариант Brainfuck, где важен только регистр букв.

Он берет первый байт и использует свой символьный код как d(поэтому новая строка означает d = 10). Остальная часть ввода - строка. EOF равен 0.

jimmy23013
источник
4

GolfScript, 95 64 байта, весь код, используемый в обеих программах

Шифрование:

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

Расшифровать:

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

Формат ввода:

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

объяснение

Расшифровать:

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.

Шифрование:

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
источник
3

Javascript (ES7 Draft) - 167 165 байт

Заимствование из @feersum использования строк и @MartinButtner использования точки с запятой;)

Шифрование:

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"

Расшифровать:

"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

Смещение для использования: 55

nderscore
источник
1
Сбой для пустых строк. Вот почему я должен был поставить, or <empty string> and <function>а не только or <function>.
feersum
@feersum теперь исправлено ... и на 2 байта короче :)
nderscore
Хм, это выглядит знакомо. ;)
Мартин Эндер
@ MartinBüttner Я не знаю, что вы имеете в виду ...;)
nderscore
2

> <> (Рыба) , 467 байт

Шифрование:

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,

Расшифровать:

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/

Две программы смещены на 3, и они принимают ввод в форме:

<2-digit offset> <text>

Смещение должно быть 2 цифры, поэтому смещение 5 должно быть введено как 05.

Это длинная отправка, но почти все символы без заполнения используются обеими программами . Есть много пробелов, которые, безусловно, можно вывести из игры, но я подумал, что программа будет более интересной в этом смысле.

Это изображение выделяет символы, используемые обеими программами.

объяснение

Основная конструкция, которая делает это возможным, _{} -> b~! , позволяет произвольно пропускать символы в программе дешифрования. Как?

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

В общем, программа шифрования ничего не делает, но программа дешифрования пропускает следующую инструкцию. Это может быть расширено до_{}! -> b~!$ , что позволяет вместо этого произвольно пропускать символы в программе шифрования .

Помимо этого, большая часть остальной части программы нажимает на числа, выполняет операции с этими числами, а затем находит способы их вытолкнуть. Например, одна полезная конструкция ~~ -> "", которая выдает два значения для программы шифрования, но ничего не выдвигает в программе дешифрования.


> <>, 149 байт

Вот менее интересная версия, в которой используется тот факт, что не пройденные инструкции фактически являются комментариями на двухмерных языках.

Шифрование:

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

Расшифровать:

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

Две программы смещены на 84 и принимают данные так же, как указано выше. Первая инструкция решает, какую половину программы выполнять, с i(вводом) поддержанием потока программы вправо в программе шифрования и ^перенаправлением потока программы вверх (цикл вокруг и возвращение снизу) в программе дешифрования.

объяснение

Для соответствующей половины программы шифрования (программа дешифрования аналогична):

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

Инструмент кодирования

Это не относится к остальной части поста выше, но я думал, что выложу это, потому что мне нужно его использовать: 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
источник
1

Perl - 131

Он принимает входные данные из аргументов командной строки.

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

Сдвиг на 26 дает другое:

q U6!*-B.+'$/IIF>[lapuKwC6+-$)/:}#-BBB*-~>yCGMLE>[lapuJwC?SOEMLC88U,;for(split//,$ARGV[1]){print chr(((ord$_)-32-$ARGV[0])%95+32)};
KSFT
источник
@ Мартен Бюттнер Вау, вознос! Это на самом деле делает работу?
KSFT
это делает, насколько я могу судить;)
Мартин Эндер