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 Definesprint("Please input your encryption key")key = raw_input(Key: )print("Please input your encryption text")text = raw_input(Text: )pos = 0ans = ""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 += 1print "
Ans:", 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的值。

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

運行效果:

首發於我的博客:python實現維吉利亞密碼加密(Vigenère cipher)

參考資料:

baike.baidu.com/item/%E

zhihu.com/question/2086

blog.csdn.net/anderslu/


推薦閱讀:

大神們幫忙解一下這串密碼,應該是四方或者二方密碼(我也不知道對不對)?
AES加密標準怎麼樣?
為什麼說密文鏈接模式已經喪失安全性?

TAG:密碼 | 加密解密 | Python |