ヴィジュネル暗号を実装してください。 ヴィジュネル暗号は、シンプルな置換暗号です。
暗号とは、文字列を暗号化、つまりエンコードするために使われるアルゴリズムです。 暗号化されていない文字列は「平文」、暗号化された文字列は「暗号文」と呼ばれます。 平文を暗号文に変換することを「エンコード」、その逆を「デコード」と呼びます。
「置換暗号」では、平文の各文字が、鍵をもとに計算された暗号文の文字に置き換えられます。 (置き換え後の文字が元の文字と同じになることもあります。)
この暗号では、鍵は"abcd"のような一連の小文字です。
平文の各文字は、鍵の対応する文字に基づく距離だけシフト(回転)されます。
鍵の"a"はシフト量0(つまり、シフトなし)を意味します。
鍵の"b"はシフト量1を意味します。
鍵の"c"はシフト量2を意味します。以下同様です。
平文の1文字目には鍵の1文字目を、平文の2文字目には鍵の2文字目を使います。以下同様です。 平文の文字がまだ残っているのに鍵の文字がなくなったら、鍵の先頭に戻ります。
鍵が"dddddd"のように1種類の文字だけを含む場合、平文のすべての文字が同じ量(この例では3)だけシフトされます。これは回転暗号、つまりシフト暗号(シーザー暗号と呼ばれることもあります)と同じになります。
たとえば、平文"iamapandabear"は"ldpdsdqgdehdu"になります。
鍵が"a"だけ(1回以上)の場合、シフト量は0で、暗号文は平文と同じになります。
ただし、通常は鍵はもっと複雑です!
鍵が"abcd"の場合、平文の文字は0、1、2、3の距離だけシフトされます。
平文が"hello"の場合、5回のシフトが必要なので鍵は折り返し、シフト量は0、1、2、3、0になります。
"hello"の各文字にこのシフトを適用すると、"hfnoo"になります。
鍵が指定されていない場合は、ラテン文字の小文字をランダムに少なくとも100文字並べた鍵を生成してください。
Cipherインターフェースの定義はcipher.goにあります。
実装はCipherインターフェースに準拠させてください。
type Cipher interface {
Encode(string) string
Decode(string) string
}
Encodeは、文字列内のA-Za-z以外の値はすべて無視することを想定しています。それらは出力には現れません。
出力は小文字に正規化されます。
暗号を取得するために使う関数は次のとおりです。
func NewCaesar() Cipher { }
func NewShift(distance int) Cipher { }
func NewVigenere(key string) Cipher { }
NewShiftの引数は、1から25、または-1から-25の範囲でなければなりません。
0は使用できません。
無効な引数の場合、NewShiftはnilを返します。
NewVigenereの引数は、小文字のa-zだけで構成されている必要があります。
すべてが文字'a'だけの値は使用できません。
無効な引数の場合、NewVigenereはnilを返します。