Pythonでヴィジュネル暗号
はじめに
ヴィジュネル暗号に関するPythonスクリプトを探しても、非効率的なものしか見つけられなかったため、自分が効率の良いと思うコードを書いた。
基本方針
ヴィジュネル暗号は、ヴィジュネル方陣を参照して暗号化と復号を行う。
ただし、ヴィジュネル方陣はkey毎に参照先をずらしているだけなため、方陣を作成する必要はない。この方陣を作成しているものしか見つからなかったため、今回の投稿に至る。
コード抜粋
def vigenere_encrypt(plaintext, key):
"""Vigenere Cipher Encrypt
key are only UPPERCASE ALPHABET[A-Z]."""
count = 0
ciphertext = ''
key = key.upper()
for s in plaintext:
if s.isupper():
ciphertext += chr(((ord(s) + ord(key[count % len(key)])) % 26) + ord('A'))
elif s.islower():
ciphertext += chr(((ord(s) + ord(key[count % len(key)]) - (ord('a') - ord('A'))) % 26) + ord('a'))
else:
ciphertext += s
count += 1
return ciphertext
def vigenere_decrypt(ciphertext, key):
"""Vigenere Cipher Decrypt
key are only UPPERCASE ALPHABET[A-Z]."""
count = 0
plaintext = ''
key = key.upper()
for s in ciphertext:
if s.isupper():
plaintext += chr(((ord(s) - ord(key[count % len(key)])) % 26) + ord('A'))
elif s.islower():
plaintext += chr(((ord(s) - ord(key[count % len(key)]) - (ord('a') - ord('A'))) % 26) + ord('a'))
else:
plaintext += s
count += 1
return plaintext
コード解説
ヴィジュネル方陣について
def vigenere_encrypt(plaintext, key):
"""Vigenere Cipher Encrypt
key are only UPPERCASE ALPHABET[A-Z]."""
count = 0
ciphertext = ''
key = key.upper()
for s in plaintext:
if s.isupper():
ciphertext += chr(((ord(s) + ord(key[count % len(key)])) % 26) + ord('A'))
elif s.islower():
ciphertext += chr(((ord(s) + ord(key[count % len(key)]) - (ord('a') - ord('A'))) % 26) + ord('a'))
else:
ciphertext += s
count += 1
return ciphertext
def vigenere_decrypt(ciphertext, key):
"""Vigenere Cipher Decrypt
key are only UPPERCASE ALPHABET[A-Z]."""
count = 0
plaintext = ''
key = key.upper()
for s in ciphertext:
if s.isupper():
plaintext += chr(((ord(s) - ord(key[count % len(key)])) % 26) + ord('A'))
elif s.islower():
plaintext += chr(((ord(s) - ord(key[count % len(key)]) - (ord('a') - ord('A'))) % 26) + ord('a'))
else:
plaintext += s
count += 1
return plaintext
ヴィジュネル方陣について
以下にヴィジュネル方陣を示す。
出典: Vigenère cipher - Wikipedia
ヴィジュネル方陣は、縦軸をKey, Aを0, Zを25とすると、
Keyの値を平文字(横軸)に自身を足し、26の法を取ったものが暗号化後の文字になるようになっている。
A...ZA...ZA...Zと続く文字列の中で、Keyの値を足したものだと考えたほうがわかりやすい方もいるかもしれない。
手作業でのヴィジュネル暗号の暗号化方法
例として、暗号鍵を「QIITA」、平文を「VIGENERE」とした場合、
ヴィジュネル方陣の縦軸のQ, 横軸のVの交差点を確認し、Lを得る。
次に、縦軸のI, 横軸のIの交差点を確認し、Q
同様に繰り返していく。(暗号鍵の最後の文字まで達したら、暗号鍵の最初の文字に戻る。)
結果として、暗号文LQOXNUZMを得る。
コード上での暗号化方法
例として、以下の1行のコードを解説していく。
ord()文字をUnicode値に変換する。chr()はその逆。
暗号鍵の最後まで達したら、暗号鍵の最初の文字に戻る部分は、key[count % len(key)]である。
ord('A')は26の法の数値をUnicode値に変換するためのものである。
ciphertext += chr(((ord(s) + ord(key[count % len(key)])) % 26) + ord('A'))
ただし、以下の性質を利用している。
>>> ord('A')
65
>>> (65*2)%26
0
上記の性質を利用しない場合、以下の記述になる。
ciphertext += chr((((ord(s) - ord('A')) + (ord(key[count % len(key)]) - ord('A'))) % 26) + ord('A'))
参考文献
ソースコード
Author And Source
この問題について(Pythonでヴィジュネル暗号), 我々は、より多くの情報をここで見つけました https://qiita.com/huwns/items/7d999835be1277217284著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .