Цезар-Цифер-Манія


22

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

(C - 32 + d) % 95 + 32

яка зміщує всіх символів на a dі циклічно переходить з ~місця в простір. На символи поза цим діапазоном (контрольні символи, такі як нові рядки, вкладки та символи поза діапазоном ASCII) не впливають.

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

Щоб зробити речі цікавішими, друга програма повинна бути цефарем Цезара першої програми. Тобто, якщо ви передаєте вихідний код першої програми самому собі, для деякого ненульового зміщення dвиведенням має бути друга програма.

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

Це кодовий гольф, тому найкоротша відповідь (у байтах) виграє. Оскільки обидві програми повинні мати однаковий розмір, їх потрібно порахувати лише один раз.

Відповіді:


12

Cjam, 40 38 37 байт

Переслати Cypher:

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

Зворотний Cypher:

"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 виправив кількість байтів. Що ви даєте як вклад?
Оптимізатор

так, моє погано, я використовував аргументи в неправильному порядку.
Деф

'"q ~' ~), 32> _ @ m <er" 9} o |% | '* 10 <]> k <cp}] "_-" 2' не працює (java.lang.RuntimeException: Несподівано})
Деф

1
@Deformyer Вам потрібно уникнути цитат у цьому рядку
Optimizer

7

Пітон 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"

Зворотний

Визначає функцію Я приймаю рядок Unicode та зміщення.

"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 байт

Моєю метою було зробити це як однолінійний 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). Це необхідно для того, щоб в одному програмі дешифрування не було жодного лапки посередині.


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

oOo КОД , 750 744 байт, весь код, що використовується в обох програмах

Занадто довго, але це, мабуть, правильний інструмент для цього ...

Шифрувати:

CcCcccccccccCcYcccCCCccCcCcCccccccCcCcccccCcCcccCcCccCccCcCCccccCcCccccCCcCccccCCccCccCcCCcccCCCcCccccCcCCcCCcCCcCcCcCccccCCccCccCccCccCccCccCccCccccccCCCcCccCccCCcCcCcccCCcCcccCcCCcCCcCcCCccCCcCCcCCcCCcCCcCCcCCcCCcCCcCCcCcccccccCccccCccccCCccccCCcCccCCcccCccccccccccCcCccCccCccCccCcCCccCCcccCcCcCccCCcccCCCcCcccccccccccccCCccCccCcCcCcccCCccccccccccCcCccccccCcCccccCCcCccCccCCcCccccccccccCCccCcCcCcccccCcCccCcCCCcCccCccCCcCccCccCccCcCcccccCcCcccCCCcCcCccccCcCccCCcCCcCCcCcCCcccCcCCcCCcCCcCCcCCcCCcCCcCCcCCcCcCcccCccCCcccccCcCcccCcccccCcccCcccCccCccCCcCcccccccccccccCCCcccCcCcCcccCcccCCCcCccCccCccCcCCccCccCcCCCcCccccCcCccccccccCcCccCccCcCCccccccCccccccccCcccCCccCccCccCCcCCcCCcCCcCcCcCcccccCcCCcCCcCCcCCcCCcCCcCCcCccCcCCcccCCccCcCcccCCcccCCCcCC

Розшифрувати:

SsSsssssssssSsisssSSSssSsSsSssssssSsSsssssSsSsssSsSssSssSsSSssssSsSssssSSsSssssSSssSssSsSSsssSSSsSssssSsSSsSSsSSsSsSsSssssSSssSssSssSssSssSssSssSssssssSSSsSssSssSSsSsSsssSSsSsssSsSSsSSsSsSSssSSsSSsSSsSSsSSsSSsSSsSSsSSsSSsSsssssssSssssSssssSSssssSSsSssSSsssSssssssssssSsSssSssSssSssSsSSssSSsssSsSsSssSSsssSSSsSsssssssssssssSSssSssSsSsSsssSSssssssssssSsSssssssSsSssssSSsSssSssSSsSssssssssssSSssSsSsSsssssSsSssSsSSSsSssSssSSsSssSssSssSsSsssssSsSsssSSSsSsSssssSsSssSSsSSsSSsSsSSsssSsSSsSSsSSsSSsSSsSSsSSsSSsSSsSsSsssSssSSsssssSsSsssSsssssSsssSsssSssSssSSsSsssssssssssssSSSsssSsSsSsssSsssSSSsSssSssSssSsSSssSssSsSSSsSssssSsSssssssssSsSssSssSsSSssssssSssssssssSsssSSssSssSssSSsSSsSSsSSsSsSsSsssssSsSSsSSsSSsSSsSSsSSsSSsSssSsSSsssSSssSsSsssSSsssSSSsSS

Brainfuck переклади:

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

oOo КОД - це варіант Brainfuck, де має значення лише випадок букв.

Він бере перший байт і використовує його код символу як d(тому новий рядок означає d = 10). Решта введення - це рядок. EOF дорівнює 0.


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.

3

Javascript (проект ES7) - 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


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>

Зсув повинен бути двозначним, тому зміщення в 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 байт

Ось менш цікава версія, яка використовує той факт, що не пропущені інструкції - це ефективно коментарі на 2D мовах.

Шифрувати:

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>


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)};

@Martin Büttner Woah, адвокат! Це на самому ділі робить роботу?
KSFT

це робить, наскільки я можу сказати;)
Мартін Ендер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.