python實現維吉利亞密碼加密(Vigenère cipher)


最近有個朋友問我關於維吉利亞密碼如何用python實現加密,研究之后發現這是個挺好玩的東西,遂決定寫篇博文記錄一下。

一、何謂維吉利亞密碼

第一列是密鑰字母列,第一行是明文字母行。不難看出維吉利亞密碼是基於凱撒加密進一步的延伸,使用了密鑰的概念來對抗字頻統計。

 

維吉尼亞密碼引入了“密鑰”的概念,即根據密鑰來決定用哪一行的密表來進行替換,以此來對抗字頻統計。假如以上面第一行代表明文字母,左面第一列代表密鑰字母,對如下明文加密:
TO BE OR NOT TO BE THAT IS THE QUESTION
當選定RELATIONS作為密鑰時,加密過程是:明文一個字母為T,第一個密鑰字母為R,因此可以找到在R行中代替T的為K,依此類推,得出對應關系如下:
密鑰:RELAT IONSR ELATI ONSRE LATIO NSREL
明文:TOBEO RNOTT OBETH ATIST HEQUE STION
密文:KSMEH ZBBLK SMEMP OGAJX SEJCS FLZSY
歷史上以維吉尼亞密表為基礎又演變出很多種加密方法,其基本元素無非是密表與密鑰,並一直沿用到二戰以后的初級電子密碼機上。
 

二、python實現

整個程序其實沒有太大的難度,順便這也是我的第一個python項目(以前都是c++),有問題的話請不吝指教。
首先我們新建一個pyhton文檔命名為“Defines”,之后直接建立之前提到的凱撒表(上圖)
CaesaTable = [['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'],
            ['b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a'],
            ['c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b'],
            ['d', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c'],
            ['e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd'],
            ['f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e'],
            ['g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f'],
            ['h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g'],
            ['i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'],
            ['j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'],
            ['k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'],
            ['l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'],
            ['m', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'],
            ['n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'],
            ['o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'],
            ['p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o'],
            ['q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p'],
            ['r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q'],
            ['s', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r'],
            ['t', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's'],
            ['u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't'],
            ['v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u'],
            ['w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v'],
            ['x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w'],
            ['y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x'],
            ['z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y']]

之后為了方便我們將字母轉換為對應的index,我們再建立一個alphabet:

alphabet = 'abcdefghijklmnopqrstuvwxyz'

 

 有了如上的定義,我們便可以實現程序的核心部分,新建文檔“main.py”。主程序如下,簡單易懂:

import Defines

print("Please input your encryption key")
key = raw_input('Key: ')

print("Please input your encryption text")
text = raw_input('Text: ')

pos = 0
ans = ""

for x in text:
    if x == " ":
        ans += " "
        continue
    i = Defines.alphabet.find(x)
    cipherKey = key[pos]
    j = Defines.alphabet.find(cipherKey)
    ans += Defines.CaesaTable[i][j]
    if pos == len(key) - 1:
        pos = 0
    else:
        pos += 1

print "\nAns:", ans

 

前七行非常簡單,是基本的輸入,得到用戶指定的Key和需要加密的Text。之后我們定義了兩個稍后會用的變量,pos用於實現key的循環,ans用作最后結果的輸出。

在循環內,首先我們判斷正在處理的這個字符是不是空格,如果是則輸出空格后直接跳過,如果不是進入下一步操作。i代表凱撒表內橫行的位置,我們使用find函數直接在先前定義的alphabet中尋找,獲得index。因為在維吉利亞加密中,密鑰長度有可能小於明文或大於名文,所以我們需要用pos作為循環的索引,之后在key中獲得當前字符對應的key。比如說明文是BIG BROTHER IS WATCH YOU,密鑰為APPLE,則對應關系如下:

BIG BROTHER IS WATCHING YOU

APP LEAPPLE AP PLEAPPLE APP

接着我們可以用一樣的方法獲得密鑰的index值,然后再先前建立的凱撒表中獲得對應的字母,添加到輸出中。最后更新索引pos的值。

至此我們的程序就完工啦,有心的讀者可以再試着完善程序的健壯性,比如遇到數字時如何加密,遇到大小寫混雜時如何處理。

運行效果:

 

參考資料:

https://baike.baidu.com/item/%E7%BB%B4%E5%90%89%E5%B0%BC%E4%BA%9A%E5%AF%86%E7%A0%81/4905472?fr=aladdin

http://www.zhihu.com/question/20864009/answer/42832661

https://blog.csdn.net/anderslu/article/details/53504300


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM