Skip to content

Vigenère Cipher (維吉尼亞密碼)

維吉尼亞密碼

維吉尼亞密碼是使用一系列凱撒密碼組成密碼字母表的加密算法,屬於多表密碼的一種簡單形式。維吉尼亞密碼以其簡單易用而著稱,同時初學者通常難以破解,因而又被稱為「不可破譯的密碼」。

維基百科

羅密歐與茱麗葉

  • 請將本封情書存於 letter.txt

O’ Romeo, my dearest dearest Romeo!

It pains me so to write this, and the very thought of you not being beside me is a stab to my heart. I urge my tears not to fall as I pen this – for you are alive, and not dead, and I must rejoice in this. It pains me so, then we are only just wed, yet we must be separated. I can still feel your light kiss lingering above my brow, when you bid me farewell. But my sweet sweet husband, my love, we will meet again, for I simply cannot bear even a minute without you at my side. I have sworn to love you and only you, and I’ll do anything just to spend the rest of my life with you. I don’t ask for forever, because forever is too far away, but I ask for a few more decades with you. I don’t ask to be born on the same day, same month, same year as you, because it is impossible, but I ask to die on the same day, same month, same year as you, so we will never ever be away from each other anymore.

Our souls are intertwined, and being apart makes me devastated. I have consulted our dearest father, Friar Lawrence, and he has a plan that will allow me to join you once again, in body and soul. But I am so afraid, what if the plan fails? I am not afraid of death, but I’m afraid of your death. Even if I cannot be with you, it hurts me to imagine you lying on a cold, hard slab of stone, colourless. No matter what my love, you must promise me that you will live on well. As you read this I believe the plan is already in action. Pray Romeo, pray that it will succeed. Pray that it will succeed, then I’ll can look into your eyes again. Pray that it will succeed, so we will never part again. Pray that it will succeed, because then I can love you again. I cannot feel your soft lips upon mine through paper, but I pour my infinite love in this words, and it will be good enough for now, knowing that your beautiful fingers have stroked and caressed these words. Farewell my dear, and it is my biggest hope that it will not be for long. To be hopelessly yours: this is my fate.

Juliet

檔案加解密

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
filename = input('請輸入要加密的檔名: ')
if filename == '':
    filename = 'letter.txt'

# 讀取明文檔
fho = open(filename, 'r', encoding='utf-8')
content = fho.read()
fho.close()

# 加密處理
alist = []
password = input('請輸入密碼: ')
plen = len(password)
for i, c in enumerate(content):
    ki = i % plen
    newc = chr(ord(c) + ord(password[ki]))
    alist.append(newc)
cipher = ''.join(alist)

# 儲存密文檔
output_file = 'encrypted.txt'
fho = open(output_file, 'w', encoding='utf-8')
fho.write(cipher)
fho.close()
print('加密完畢! 密文檔名:', output_file)

維吉尼亞加密工具

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
from tkinter import *

# 加密函式
def encrypt():
    alist = []
    password = ent9.get()
    plen = len(password)
    plain = txt1.get(1.0, END)
    for i, c in enumerate(plain):
        ki = i % plen
        newc = chr(ord(c) + ord(password[ki]))
        alist.append(newc)
    cipher = ''.join(alist)
    txt2.delete(1.0, END)
    txt2.insert(1.0, cipher)

# 解密函式
def decrypt():
    alist = []
    password = ent9.get()
    plen = len(password)
    cipher = txt2.get(1.0, END)
    for i, c in enumerate(cipher[:-1]):
        ki = i % plen
        newc = chr(ord(c) - ord(password[ki]))
        alist.append(newc)
    plain = ''.join(alist)
    txt1.delete(1.0, END)
    txt1.insert(1.0, plain)

# 執行視窗程式
twin = Tk()
twin.title('維吉尼亞加密工具')
width = 640
height = 480
# 不可調整視窗大小
twin.resizable(False, False)
x = (twin.winfo_screenwidth() // 2) - (width // 2)
y = (twin.winfo_screenheight() // 2) - (height // 2)
twin.geometry('{}x{}+{}+{}'.format(width, height, x, y))
# 自訂字型
myfont = ('Consolas', 11)
# 明文
lbl1 = Label(twin, font=myfont, text='明文')
lbl1.pack(fill=X)
frame1 = Frame(twin)
frame1.pack(fill=X)
sbr1 = Scrollbar(frame1)
sbr1.pack(side=RIGHT, fill=Y)
txt1 = Text(frame1, font=myfont, yscrollcommand=sbr1.set, height=10)
sbr1.config(command=txt1.yview)
txt1.pack(fill=X, padx=10, pady=5)
# 密文
frame2 = Frame(twin)
lbl2 = Label(twin, font=myfont, text='密文')
lbl2.pack(fill=X)
frame2.pack(fill=X)
sbr2 = Scrollbar(frame2)
sbr2.pack(side=RIGHT, fill=Y)
txt2 = Text(frame2, font=myfont, yscrollcommand=sbr2.set, height=10)
sbr2.config(command=txt2.yview)
txt2.pack(fill=X, padx=10, pady=5)
# 密碼與功能
frame3 = Frame(twin)
frame3.pack(fill=X)
lbl9 = Label(frame3, font=myfont, text='密碼')
ent9 = Entry(frame3, font=myfont)
ent9.insert(0, 'password')
btn1 = Button(frame3, font=myfont, text='加密', command=encrypt)
btn2 = Button(frame3, font=myfont, text='解密', command=decrypt)
for comp in (lbl9, ent9, btn1, btn2):
    comp.pack(padx=10, pady=5, side=LEFT)

twin.mainloop()