Розшифруйте шифротекст Віньєра


28

Віженер Шифр був простим поліалфавітних шифром , який в основному застосовується один з декількох шифрів Цезаря, в відповідно до ключа. В основному букви в ключі вказують, який зміщений алфавіт використовувати. З цією метою був простий інструмент під назвою площа Віньєра:

введіть тут опис зображення

Тут кожен рядок є окремим алфавітом, починаючи з відповідної літери ключа. Потім стовпці використовуються для визначення зашифрованої літери. Розшифровка працює дуже однаково, лише навпаки.

Припустимо, ми хочемо зашифрувати рядок CODEGOLF. Нам також потрібен ключ. У цьому випадку ключ повинен бути FOOBAR. Коли ключ коротший від простого тексту, ми продовжуємо його повторенням, тому власне ключ, який ми використовуємо, є FOOBARFO. Зараз ми шукаємо першу букву ключа, яка Fповинна знайти алфавіт. Це починається, можливо, не дивно, з F. Тепер ми знаходимо стовпчик з першою буквою простого тексту і отриманою літерою є H. Для другої літери ми маємо Oяк основну букву, так і простий текстовий лист, в результаті чого C. Продовжуючи цей шлях, ми нарешті отримуємо HCRFGFQT.

Завдання

Ваше завдання зараз - розшифрувати повідомлення, надавши ключ. Однак, оскільки ми переросли в 16 столітті і маємо комп'ютери, ми повинні хоча б підтримувати трохи більший алфавіт:

abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789

Побудова площі Віньєра досі дуже однакова, і шифр все ще працює так само. Це просто трохи ... непросто, щоб дати тут повністю.

Вхідні дані

Введення подається на стандартному введенні у вигляді двох окремих рядків тексту, кожен із яких закінчується розривом рядка. Перший рядок містить ключ, а другий - шифротекст.

Вихідні дані

Єдиний рядок, що містить розшифроване повідомлення.

Умова виграшу

Оскільки шифрування іноді розглядають як зброю, код повинен бути коротким для полегшення легкої контрабанди. Чим коротше, тим краще, оскільки це зменшує ймовірність виявлення.

Зразок введення 1

Key
miQ2eEO

Вихід вибірки 1

Message

Зразок введення 2

ThisIsAKey
CoqKuGRUw29BiDTQmOpJFpBzlMMLiPb8alGruFbu

Вибірка зразка 2

ThisWorksEquallyWellWithNumbers123894576

Минув тиждень. Наразі найкоротше рішення прийнято. Для зацікавлених у нашому конкурсі ми мали такі подання та тривалість:

130 - Python
146 - Haskell
195 - C
197 - C
267 - VB.NET

І наші власні рішення, які не були класифіковані з іншими:

108 - Ruby
139 - PowerShell


Здається, що це може бути корисним для друку площі Віньєра.
Ерік Аутгольфер

Відповіді:


10

Гольфскрипт - 48 символів

n%~.,@*\{\(123,97>91,65>+58,48>+:|?@|?\-|=}%\0<+

Ніяких хитрощів у цьому!


+1 Я лягав спати, думаючи, що повинен бути спосіб знизити це до ~ 50, тепер я бачу, що це можливо, але, мабуть, я б не встиг цього незабаром
gnibbler

8

Файл MS-DOS 16bit .COM - 87 байт

Base64, кодований двійковим кодом ( дотримуючись цього посилання на декодер )

v1cBi8/oQACJ/ovv6DkAi9msitAqF3MDgMI+gMJhgPp6dguA6jqA+lp2A4DqK80hO/d0IkM563TW69YsYXMIBCB9AgQrBBqqtAHNITwNdev+xLIKzSHD

Зазвичай ви самі пишете короткий вихідний код для гри в гольф. Хоча це, мабуть, не неможливо, я якось сумніваюся в цьому.
Джої

@Joey: Що, ви ніколи не передавали інструкції машинного коду! Тільки чого вони навчають молодих людей у ​​ці дні! ;-)
Skizz

Скізз: Я так і зробив. Не в Base64, однак;) (у нас був клас кілька років тому, коли нам довелося писати програми для Siemens 80C167 в асемблері - і на іспитах також збирати їх у машинний код. Я думав про те, щоб розкопати ці знання для Assembler Вишукане завдання, але у нас не було вихідних засобів [принаймні, вони змінювались]).
Joey

@Joey: Base64 - це просто зручність для інших користувачів на цьому веб-сайті, його легко розшифрувати та зберегти як бінарний файл (посилання у відповіді має таку можливість).
Скізз

Ах, вибачте. Я думав, ти б дав довжину Base64. Що ж, Кріс одного разу включив до рішення довільних персонажів і просто дав гексадум крім своєї відповіді. Я робив подібне в прогнозі погоди.
Джої

8

APL (45)

∆[⍙⍳⍨¨⌽∘∆¨(⍴⍙←⍞)⍴1-⍨⍞⍳⍨∆←⎕D,⍨⎕A,⍨⎕UCS 96+⍳26]

Пояснення:

  • ∆←⎕D,⍨⎕A,⍨⎕UCS 96+⍳26: згенерувати алфавіт (цифри ( ⎕D), слідувати за літерами ( ⎕A), слідувати малими літерами ( ⎕UCS 96+⍳26, значення унікоду від 97 до 122).

  • 1-⍨⍞⍳⍨∆: прочитайте рядок (ключ), знайдіть позицію кожного символу в алфавіті та відніміть його (масиви за замовчуванням є однією, тому перенесення на ці значення безпосередньо змістить алфавіт занадто далеко).

  • (⍴⍙←⍞)⍴: прочитайте інший рядок (повідомлення) та повторіть індекси ключа, щоб він мав довжину повідомлення.
  • ⌽∘∆¨: обертати алфавіт за індексами, що належать клавіші
  • ⍙⍳⍨¨: шукайте кожного символу повідомлення у відповідному зміщеному алфавіті
  • ∆[... ]: шукайте задані індекси у звичайному алфавіті, даючи відповідні символи.

6

Рубі - 132 127 122 109 100 100 символів

a,b=*$<
c=*?a..?z,*?A..?Z,*?0..?9
(b.size-1).times{|i|$><<c[c.index(b[i])-c.index(a[i%(a.size-1)])]}

Використовуйте *$<замість $<.to_aі вбудовуючи лямбда, щоб зберегти ще кілька байт. - Ventero 5 хвилин тому
Joey

Дякую @Joey, я витягнув цю лямбда, щоб зберегти персонажів і якось пропустив, що це насправді коштувало дорожче.
Nemo157

5

Пітон - 122 символи

from string import*
L=letters+digits
R=raw_input
K,T=R(),R()
F=L.find
print"".join(L[F(i)-F(j)]for i,j in zip(T,K*len(T)))

5

J, 65 символів

v=:4 : 'a{~x(62|[:-/"1 a i.[,.#@[$])y[a=.a.{~62{.;97 65 48+/i.26'

Не повністю відповідає специфікації, оскільки вона визначена як дієслово, а не як введення, але я все-таки публікую його з наміром пізніше познайомитися з ним.

Використання:

   'miQ2eEO' v 'Key'
Message
   'CoqKuGRUw29BiDTQmOpJFpBzlMMLiPb8alGruFbu' v 'ThisIsAKey'
ThisWorksEquallyWellWithNumbers123894576

4

Perl, 95 символів

Perl 5.010, запустіть із perl -E:

%a=map{$_,$n++}@a=(a..z,A..Z,0..9);@k=<>=~/./g;
$_=<>;s/./$a[($a{$&}-$a{$k[$i++%@k]})%62]/ge;say

3

Пітон - 144 143 140 136 125 символів

Напевно, не найкращий, але ей:

from string import*
l=letters+digits
r=l.find
q=raw_input
k=q()
print"".join(l[(r(j)-r(k[i%len(k)]))%62]for i,j in enumerate(q()))

Ага, я збирався розмістити щось саме так. Ви можете призначити raw_input змінній, 3 або близько символів.
Хуан

3

Гольфскрипт - 65 символів

Ще потрібно більше гольфу. На даний момент T - текст, K - ключ, L - список букв

n%):T,\~*:K;''26,{97+}%+.{32^}%10,{48+}%++:L;T{L\?K(L\?\:K;-L\=}%

3

К, 81 61

k:0:0;,/$(m!+(`$'m)!+{(1_x),1#x}\m:,/.Q`a`A`n)[(#v)#k]?'v:0:0

.

k)k:0:0;,/$(m!+(`$'m)!+{(1_x),1#x}\m:,/.Q`a`A`n)[(#v)#k]?'v:0:0
ThisIsAKey
CoqKuGRUw29BiDTQmOpJFpBzlMMLiPb8alGruFbu
"ThisWorksEquallyWellWithNumbers123894576"

2

Perl, 115 символів

$a=join'',@A=(a..z,A..Z,0..9);$_=<>;chop;@K=split//;$_=<>;s/./$A[(index($a,$&)-index($a,$K[$-[0]%@K]))%@A]/ge;print

2

Гольфскрипт - 92 символи

n%~\.,:l;{0\{1$+\)\}%\;}:&;26'a'*&26'A'*&+10'0'*&+\@.,,{.l%3$=4$?\2$=4$?\- 62%3$\>1<}%\;\;\;

Напевно, набагато довше, ніж потрібно. Ще намагаюся обвести голову навколо GS.

Ось "невольф" і коментується версія

n%~\.,:l;
{0\{1$+\)\}%\;}:&; # This would be sortof an equivalent for range applied to strings
26'a'*&26'A'*&+10'0'*&+\@., # This mess generates the dictionary string,
# l = len(key)
# 0 dictionary (letters + digits)
# 1 key
# 2 text
{
    # 3 index
    .   #+1 Duplicate the index

    # Find the index of the key letter
    l%  #+1 Indice modulo key
    3$  #+2 Duplicate the key
    =   #+1 Get the key letter
    4$? #+1 Search the letters index

    # Find the index of the text letter
    \   #+1 Get the index
    2$  #+2 Get the text
    =   #+1 Get the text letter
    4$? #+0 Search the letters index

    # 3 key index
    # 4 letter index

    \-   #+1 get the index of the new letter

    62% #+1 wrap the index around the dictionary

    3$ #+2 Get the dictionary

    \> #+1 remove the first part of the dict around the target letter

    1< #+1 remove everythin after 
}%
\;
\;
\;

2

VBA, 288

Не дуже перемагає вказаний результат VB.NET (але я наближаюся):

Sub h(k,s)
v=Chr(0)
Z=Split(StrConv("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",64),v)
a=Split(StrConv(s,64),v):b=Split(StrConv(k,64),v)
For l=0 To Len(s)-1
j=l Mod Len(k)
g=0
For i=0 To 62:g=g+i*((Z(i)=b(j))-(Z(i)=a(l))):Next
x=x &Z(IIf(g<0,g+62,g))
Next
s=x
End Sub

Використання:

Sub test()
k = "ThisIsAKey"
s = "CoqKuGRUw29BiDTQmOpJFpBzlMMLiPb8alGruFbu"
h k, s
MsgBox s
End Sub

Дякую Джої за пораду!


g=g+IIf(Z(i)=c,i,0)-IIf(Z(i)=d,i,0)був би один кандидат, якого я можу помітити. А також перевірити, чи розуміються закінчення рядків LF за допомогою VBA. Принаймні, один простір у цьому теж x=x & Z(g)може бути залишений.
Джої

Інший спосіб написання рядка: g=g+i*((Z(i)=d)-(Z(i)=c)) (бо Trueв VB -1). Можливо, це працює.
Джої

Дякую за відгук, @Joey. Я шукаю будь-які інші вдосконалення та додам це.
Гаффі,

2

С, 186

Трохи запізнюється, але .. (лінії розбиті, щоб уникнути горизонтальної смуги прокрутки).

char a[99],*s,*t;k,j;main(int m,char**v)
{for(;j<26;++j)a[j]=32|(a[j+26]=65+j),
a[52+j]=48+j;while(*v[2])
putchar(a[s=strchr(a,v[1][k++%strlen(v[1])])
,t=strchr(a,*v[2]++),s>t?t-s+62:t-s]);}

Нерозривні лінії

char a[99],*s,*t;k,j;main(int m,char**v){for(;j<26;++j)a[j]=32|(a[j+26]=65+j),a[52+j]=48+j;while(*v[2])putchar(a[s=strchr(a,v[1][k++%strlen(v[1])]),t=strchr(a,*v[2]++),s>t?t-s+62:t-s]);}

Дискусію щодо процесу гольфу цього коду можна знайти тут: http://prob-slv.blogspot.com/2013/04/code-golf.html


2

JavaScript 248

var v= 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
function d(k,c){var a,b,o,x
a=k.charAt(0)
x=v.indexOf(a)
b=v.substr(x)+v.substring(0,x)
o= v.charAt(b.indexOf(c.charAt(0)))
k=k.substr(1)+a
c=c.substr(1)
return (c)?o+d(k,c):o}

1

Хаскелл (169)

import List
main=do c<-y;t<-y;putStrLn$map((k!!).(`mod`62))$zipWith(-)(g t)(cycle$g c)
k=['a'..'z']++['A'..'Z']++['0'..'9']
y=getLine
f(Just x)=x
g=map$f.(`elemIndex`k)

1

J: 91 символ

[:{&{.&t({&t"0&(({.t=.1|.^:(i.62)a.{~(97+i.26),(65+i.26),48+i.10)&i.)"0@:$~#)|:@(i."1.,"0)]

Наприклад:

    g=:[:{&{.&t({&t"0&(({.t=.1|.^:(i.62)a.{~(97+i.26),(65+i.26),48+i.10)&i.)"0@:$~#)|:@(i."1.,"0)]
    'ThisIsAKey' g 'CoqKuGRUw29BiDTQmOpJFpBzlMMLiPb8alGruFbu'
ThisWorksEquallyWellWithNumbers123894576
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.