不知不覺過了16天惹! 正式超過一半!!!真佩服我自己可以堅持到現在w希望不要在甚麼29天斷掉XD繼續努力GOGO,今天要來實作維吉尼亞密碼解碼器
輸入明文跟金鑰->把金鑰變得跟明文一樣長->
將明文字母與對應位置的金鑰字母相加得到密文C,Ci=Pi+Ki (mod26)
首先,設 明文plaintext = 'ATTACKATDAWN', 金鑰key = 'LEMON'
之後要把key變得跟plaintext一樣長,方法為重複字串,
所以key會變成
key = 'LEMONLENONLE'(紅色為重複的部分)
之後將明文字母與對應位置的金鑰字母相加並mod 26得到密文encryptext
A~Z,用數字表示為0 ~ 25
e.g. A = 0, L = 11, (0 + 11)%26 -> L
e.g. T = 19, E = 4, (19 + 4)%26 -> X
encryptext = 'LXFOPVEFRNHR'
如果要解密的話就
將密文字母與對應位置的金鑰字母相減得到明文Pi=Ei-Ki (mod26)
這樣減484很麻煩,所以也可以利用查表的方式!
我們舉例Pi = T, Ki = E
看交集,得出加密後為X
了解了這個加密在幹嘛後,來把它用python呈現出來
plaintext : 明文, encryptext : 密文, key : 金鑰
舉例為plaintext都為英文字母大寫的情況下
for i in range(0, len(plaintext)):
encryptext += chr(((ord(plaintext[i]) - ord('A') + ord(key[i % len(key)].upper()) - ord('A')) % 26) + ord('A'))
利用迴圈跑plaintext字串,
利用公式(!?)Ci=Pi+Ki (mod26)
最後要在+一個ord('A')是因為公式算出來會是0~25的第幾個,
但ASCII碼表,大寫英文字母是從A(65)開始,所以我們要再+ord('A')
key[i % len(key)].upper() -> 把key[i % len(key)]變大寫
key[i % len(key)].lower() -> 把key[i % len(key)]變小寫
for i in range(0, len(plaintext)):
if plaintext[i].isalpha():
if plaintext[i].isupper():
encryptext += chr(((ord(plaintext[i]) - ord('A') + ord(key[i % len(key)].upper()) - ord('A')) % 26) + ord('A'))
else :
encryptext += chr(((ord(plaintext[i]) - ord('a') + ord(key[i % len(key)].lower()) - ord('a')) % 26) + ord('a'))
else:
print(plaintext[i])
print(encryptext)
接下來就可以製作Vigenère加/解碼器了!
流程如下
def decrypt(encryptext, key):
plaintext = ""
for i in range(0, len(encryptext)):
if encryptext[i].isalpha():
if encryptext[i].isupper():
plaintext += chr(( ((ord(encryptext[i]) - ord('A')) - (ord(key[i % len(key)].upper()) - ord('A'))) % 26) + ord('A'))
else :
plaintext += chr(( ((ord(encryptext[i]) - ord('a')) - (ord(key[i % len(key)].lower()) - ord('a'))) % 26) + ord('a'))
else:
print(encryptext[i])
return plaintext
def encrypt(plaintext, key):
encryptext = ""
for i in range(0, len(plaintext)):
if plaintext[i].isalpha():
if plaintext[i].isupper():
encryptext += chr(((ord(plaintext[i]) - ord('A') + ord(key[i % len(key)].upper()) - ord('A')) % 26) + ord('A'))
else :
encryptext += chr(((ord(plaintext[i]) - ord('a') + ord(key[i % len(key)].lower()) - ord('a')) % 26) + ord('a'))
else:
print(plaintext[i])
return encryptext
def main():
plaintext = str(input('input string\n>>'))
select = int(input("input 1 or 2 (Encode / Decode)\n>>"))
key = str(input("input key\n>>"))
if select == 1 :
print("encryptext :", encrypt(plaintext, key))
else :
print("decryptext :", decrypt(plaintext, key))
if __name__ == "__main__":
main()
output
plaintext : AtTACKATDawN, key : LeMOn
結果相同
encryptext : LxFOPVEFRnhR, key : LeMOn
結果相同
今天完成了維吉尼亞解碼器,也正式了解到他是怎麼加密的XD之前遇到這類型的題目,就是直接丟網路上,所以也沒怎麼去了解它,明天繼續製作我們的解碼器!