Vigenère şifresini çözmek


28

Vijiner şifre temelde bir anahtar göre, birkaç Sezar şifrelerin birini uygulanan basit bir polyalphabetic şifre idi. Temel olarak, tuştaki harfler hangi alfabenin kaydırılacağını gösterir. Bu amaçla Vigenère Meydanı adı verilen basit bir araç vardı :

görüntü tanımını buraya girin

Burada her satır, anahtarın karşılık gelen harfiyle başlayan ayrı bir alfabedir. Sütunlar şifreli harfi belirlemek için kullanılır. Şifre çözme, aynı şekilde çalışır, ancak tam tersi.

Dize şifrelemek istediğimizi varsayalım CODEGOLF. Ayrıca bir anahtara ihtiyacımız var. Bu durumda anahtar olacaktır FOOBAR. Anahtar, düz metinden daha kısa olduğunda, tekrarlayarak genişletiriz, bu nedenle kullandığımız gerçek anahtardır FOOBARFO. Şimdi Falfabenin yerini bulmak için anahtarın ilk harfini araştırıyoruz . Belki şaşırtıcı bir şekilde ile başlar F. Şimdi sütunu düz metnin ilk harfiyle bulduk ve ortaya çıkan harf H. İkinci harf Oiçin anahtar harf ve düz metin harf olarak karşımıza çıkmaktadır C. Bu şekilde devam ederek nihayet elde ederiz HCRFGFQT.

Görev

Şimdi göreviniz bir anahtar verilen mesajları deşifre etmektir. Bununla birlikte, 16. yüzyıldan beri genişlediğimiz ve bilgisayarlara sahip olduğumuzdan, en azından biraz daha büyük bir alfabeyi desteklemeliyiz:

abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789

Vigenère meydanının yapımı hala hemen hemen aynıdır ve şifre hala aynı şekilde çalışmaktadır. Sadece biraz ... buraya tam olarak vermek hantal.

Giriş

Girdi, standart girişte her biri satır sonu ile sonlandırılan iki ayrı metin satırı olarak verilir. İlk satır anahtarı, ikincisi şifreli metni içerir.

Çıktı

Şifresi çözülmüş mesajı içeren tek bir satır.

Kazanma koşulu

Şifreleme bazen bir silah olarak kabul edildiğinden, kolay kaçakçılığı kolaylaştırmak için kodun kısa olması gerekir. Ne kadar kısa olursa, keşif olasılığını azaltır.

Örnek giriş 1

Key
miQ2eEO

Örnek çıktı 1

Message

Örnek giriş 2

ThisIsAKey
CoqKuGRUw29BiDTQmOpJFpBzlMMLiPb8alGruFbu

Örnek çıktı 2

ThisWorksEquallyWellWithNumbers123894576

Bir hafta geçti. Şu anda en kısa çözüm kabul edildi. İlgilenenler için, yarışmamızda aşağıdaki önerileri ve uzunlukları aldık:

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

Ve diğerleri ile sıralanmayan kendi çözümlerimiz:

108 - Yakut
139 - PowerShell


Vigenère meydanını basmak için bu yararlı olabilir gibi görünüyor .
Outgolfer Erik,

Yanıtlar:


10

Golfscript - 48 karakter

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

Bunda hile yok!


+1 Yatağa gitmenin bir yolu olduğunu düşünerek yatağa gittim ~ 50'ye, şimdi bunun mümkün olduğunu görüyorum ama muhtemelen yakında herhangi bir zamanda başaramazdım
gnibbler

8

MS-DOS 16bit .COM dosyası - 87 bayt

Base64 kodlanmış ikili ( bir kod çözücü için bu bağlantının ardından )

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

Genellikle golf için kısa kaynak kodunu yazarsın. Muhtemelen imkansız olmasa da, bir şekilde bundan şüpheliyim.
Joey,

@Joey: Ne, kodlanmış makine kodu talimatlarını asla vermediniz! Bugünlerde gençlere ne öğretiyorlar? ;-)
Skizz

Skizz: Yaptım. Ancak Base64'te değil;) (birkaç yıl önce Siemens 80C167 için assembler programlarını yazmak zorunda kaldığımız bir sınıf vardı - ve sınavlarda da bunları makine koduna birleştirdik. Assembler için bu bilgiyi kazmayı düşündüm. Quine görevi, ancak hiçbir çıkış tesisimiz yoktu (en azından onlar değişti).
Joey,

@Joey: Base64 bu sitedeki diğer kullanıcılar için sadece bir kolaylık sağlıyor, bir ikili dosya olarak kodu çözmek ve kaydetmek kolaydır (cevabınızdaki bağlantı bu seçeneğe sahiptir).
Skizz

Aah, özür dilerim. Base64'ün uzunluğunu vereceğini düşünmüştüm64. Chris, bir zamanlar rastgele karakterleri bir çözüme dahil etti ve cevabının yanı sıra bir hexdump verdi. Hava Durumu'nda da benzer şeyler yaptım.
Joey,

8

APL (45)

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

Açıklama:

  • ∆←⎕D,⍨⎕A,⍨⎕UCS 96+⍳26: alfabeyi oluşturur (sayılar ( ⎕D) harfleri takip eder ( ⎕A) küçük harfleri takip eder ( ⎕UCS 96+⍳26, unicode değerleri 97 ila 122).

  • 1-⍨⍞⍳⍨∆: bir satır (anahtar) oku, alfabedeki her karakterin konumunu bul ve birini çıkar (diziler varsayılan olarak tek tabanlıdır, bu yüzden bu değerlere göre kaydırmak alfabeyi bir o kadar uzağa kaydırır).

  • (⍴⍙←⍞)⍴: başka bir satırı (mesaj) oku ve tuşun indekslerini mesajın uzunluğu kadar olacak şekilde tekrarla.
  • ⌽∘∆¨: alfabeyi, anahtarın ait olduğu dizinlere göre döndür
  • ⍙⍳⍨¨: mesajdaki her karaktere karşılık gelen karakterleri değiştir
  • ∆[... ]: verilen endeksleri normal alfabede arayarak karşılık gelen karakterleri araştırarak.

6

Yakut - 132 127 122 109 100 karakter

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

Yerine *$<kullanın $<.to_ave lambda satır içi başka bir kaç bayttan tasarruf etmek için kullanın . - Ventero 5 dak önce
Joey

Thanks @Joey, o lambda'yı karakterleri kurtarmak için çıkardım ve bir şekilde daha pahalıya mal olduğunu özledim.
Nemo157

5

Python - 122 karakter

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 karakter

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

Girdiyi almaktan ziyade bir fiil olarak tanımlandığından belirtimi tam olarak karşılamıyor, ancak yine de ileriki bir tarihte uğraşmak niyetiyle gönderiyorum.

Kullanımı:

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

4

Perl, 95 karakter

Perl 5.010, şöyle 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

Python - 144 143 140 136 125 karakter

Muhtemelen en iyisi değil, ama hey:

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

Huh, aynen böyle bir şey göndermek üzereydim. Raw_input değişkenine, 3 karaktere veya karaktere atayabilirsiniz.
Juan

3

Golfscript - 65 karakter

Hala daha çok golf oynamak gerekiyor. Şimdilik, T metin, K Anahtar, L harflerin listesi

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

3

K, 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 karakter

$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

Golfscript - 92 karakter

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

Muhtemelen olması gerekenden çok daha uzun. Hala kafamı GS ile dolaştırmaya çalışıyorum.

Heres "ungolfed" ve yorum yaptı

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

Listelenen VB.NET puanını pek geçmiyor (ancak yaklaşıyorum):

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

Kullanımı:

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

Joey bahşiş için teşekkürler !


g=g+IIf(Z(i)=c,i,0)-IIf(Z(i)=d,i,0)tespit edebileceğim bir aday olurdu. LF satır sonlarının VBA tarafından anlaşılıp anlaşılmadığını denemenin yanı sıra. Sanırım en az bir tane boşluk x=x & Z(g)bırakılmış olabilir.
Joey

Satırı yazmanın başka bir yolu: g=g+i*((Z(i)=d)-(Z(i)=c)) (çünkü TrueVB'de −1'dir). Çalışıyor olabilir.
Joey,

Geri bildiriminiz için teşekkür ederiz, @Joey. Başka iyileştirmeler arayacağım ve bunu da ekleyeceğim.
Gaffi

2

Cı, 186

Biraz geç ama .. (yatay kaydırma çubuğunu önlemek için kesik çizgiler)

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

Kırık çizgiler

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

Bu kodu golf süreciyle ilgili bir tartışma burada bulunabilir: 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

Haskell (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 karakter

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

Örneğin:

    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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.