Vigenère暗号文を解読する


28

ヴィジュネル暗号は、鍵によれば、基本的にいくつかのシーザー暗号のいずれかを適用単純polyalphabetic暗号ました。基本的に、キー内の文字は、どのシフトアルファベットを使用するかを示します。そのために、Vigenèreスクエアと呼ばれるシンプルなツールがありました

ここに画像の説明を入力してください

ここで、各行は、キーの対応する文字で始まる個別のアルファベットです。列は、暗号化された文字を決定するために使用されます。復号化はほぼ同じ方法で機能しますが、逆も同様です。

文字列を暗号化するとしますCODEGOLF。キーも必要です。この場合、キーはであるものとしますFOOBAR。キーがプレーンテキストより短い場合、繰り返してキーを拡張するため、実際に使用するキーはですFOOBARFO。キーの最初の文字Fを検索します。これはアルファベットを見つけるためのものです。おそらく驚くことではありませんが、で始まりFます。これで、プレーンテキストの最初の文字が含まれる列が見つかり、結果の文字はHです。2番目の文字にはO、キー文字とプレーンテキスト文字があり、結果はになりCます。そのように続けると、ようやく手に入りHCRFGFQTます。

仕事

ここでのタスクは、キーを指定してメッセージを解読することです。ただし、16世紀を超えてコンピューターを所有しているため、少なくとも少し大きいアルファベットをサポートする必要があります。

abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789

Vigenère広場の構造はまだ非常に同じであり、暗号はまだ同じように機能します。少しだけ...ここで完全に説明するのは扱いにくいです。

入力

入力は、それぞれが改行で終わる2行のテキストとして標準入力に与えられます。最初の行にはキーが含まれ、2番目の行には暗号文が含まれます。

出力

解読されたメッセージを含む単一行。

勝利条件

暗号化は武器と見なされることもあるため、密輸を容易にするためにコードは短くする必要があります。発見の可能性を減らすため、短いほど良い。

サンプル入力1

Key
miQ2eEO

サンプル出力1

Message

サンプル入力2

ThisIsAKey
CoqKuGRUw29BiDTQmOpJFpBzlMMLiPb8alGruFbu

サンプル出力2

ThisWorksEquallyWellWithNumbers123894576

1週間が経過しました。現在最短の解決策が受け入れられています。興味のある方のために、私たちのコンテストでは、以下の提出物と長さがありました。

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

そして、他とはランク付けされなかった独自のソリューション:

108 – Ruby
139 – PowerShell


と思われ、これは Vigenère広場を印刷すると便利です。
エリックアウトゴルファー

回答:


10

Golfscript-48文字

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

これにはトリックはありません!


+1これを50に下げる方法があるに違いないと考えて就寝しましたが、今では可能だと思いますが、おそらくすぐには管理できなかったでしょう
ニブラー

8

MS-DOS 16ビット.COMファイル-87バイト

Base64エンコードバイナリ(デコーダーのこのリンクをたどる

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

通常、ゴルフ用の短いソースコードを自分で記述します。おそらく不可能ではないかもしれませんが、私はこれで何らかの形でそれを疑います。
ジョーイ

@Joey:なんと、エンコードされたマシンコードの命令を手渡したことはありません!彼らは最近、若者に何を教えているのでしょう!;-)
スキズ

Skizz:やった。ただし、Base64ではありません;)(数年前にアセンブラーでシーメンス80C167のプログラムを作成する必要があったクラスがありました。また、試験ではそれらをマシンコードにアセンブルしました。かなりの作業ですが、出力機能はありませんでした[少なくとも、変化しました])。
ジョーイ

@Joey:Base64は、このサイトの他のユーザーにとって便利なだけです。デコードしてバイナリファイルとして保存するのは簡単です(回答のリンクにはそのオプションがあります)。
スキズ

ああ、ごめんなさい。Base64の長さを指定したと思います。まあ、クリスはかつてソリューションに任意の文字を含め、彼の答えに加えてhexdumpを与えました。天気予報でも同様のことをしました。
ジョーイ

8

APL(45)

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

説明:

  • ∆←⎕D,⍨⎕A,⍨⎕UCS 96+⍳26:アルファベットを生成します(数字(⎕D)は文字(⎕A)に続き、小文字(⎕UCS 96+⍳26、97から122までのUnicode値)に続きます)。

  • 1-⍨⍞⍳⍨∆:行(キー)を読み取り、アルファベットの各文字の位置を見つけて、1を減算します(デフォルトでは配列は1から始まるため、これらの値で直接シフトするとアルファベットが1つ移動しすぎます)。

  • (⍴⍙←⍞)⍴:別の行(メッセージ)を読み取り、メッセージの長さを持つようにキーのインデックスを繰り返します。
  • ⌽∘∆¨:キーに属するインデックスでアルファベットを回転させます
  • ⍙⍳⍨¨:対応するシフトされたアルファベットでメッセージの各文字を検索します
  • ∆[... ]:指定されたインデックスを通常のアルファベットで検索し、対応する文字を提供します。

6

ルビー- 132の127 122 109 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インラインを使用して、さらに数バイトを節約します。– ヴェンテロ 5分前
ジョーイ

@Joeyのおかげで、私はそのラムダを引き出してキャラクターを保存しましたが、実際にはもっとコストがかかることを何とか逃しました。
Nemo157

5

Python-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

Golfscript-65文字

それでももっとゴルフする必要があります。今のところ、Tはテキスト、Kはキー、Lは文字のリストです

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文字

$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文字

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

おそらく必要以上に長い。まだGSを回避しようとしています。

Heres "ungolfed"およびコメント付きバージョン

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)私が見つけることができる1つの候補者になります。LFの行末がVBAによって理解されるかどうかを試すだけでなく。少なくとも1つのスペースをx=x & Z(g)省くこともできると思います。
ジョーイ

行を記述する別の方法:g=g+i*((Z(i)=d)-(Z(i)=c)) TrueVBでは-1であるため)。それが機能している可能性があります。
ジョーイ

@Joey、フィードバックをありがとう。他の改善点を探して追加します
。-ガフィ

2

C、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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.