# vigenere.py, a modification of the Vigenere ciphering program
# Uses Tkinter
import sys, string, tkMessageBox
from Tkinter import *
# -- The application class
class Vigenere:
# Initialize new instances of Vigenere
def __init__(self, root):
self.root = root
self.makeStringVars()
self.makeWidgets()
# Initialize all widget-bound StringVars
def makeStringVars(self):
self.sv_message = StringVar(); self.sv_message.set("")
self.sv_keyword = StringVar(); self.sv_keyword.set("")
self.sv_alphakey = StringVar(); self.sv_alphakey.set("")
# Initialize all Tkinter widgets
def makeWidgets(self):
# Set the application window's title and make it unresizable
self.root.title("Vigenere")
self.root.resizable(0, 0)
# Make the main Frame for all widgets
fr_main = Frame(self.root); fr_main.pack()
# Make the Frame for the message widgets
fr_message = Frame(fr_main); fr_message.pack()
# Make the Frames for all keyword and alphakey widgets
fr_keys = Frame(fr_main); fr_keys.pack(pady=10)
fr_labels = Frame(fr_keys); fr_labels.pack(side=LEFT)
fr_entries = Frame(fr_keys); fr_entries.pack(side=LEFT)
# Make the Frame for the 'Encipher' and 'Decipher' Buttons
fr_buttons = Frame(fr_main); fr_buttons.pack(pady=10)
# Make the message Label and Entry
lb_text = Label(fr_message, text="Text or Ciphertext")
lb_text.pack()
self.en_message = Entry(fr_message, width=60,
textvariable=self.sv_message)
self.en_message.pack()
self.en_message.focus_set()
# Make the keyword and alphakey Labels and Entries
lb_keyword = Label(fr_labels, text="Keyword:")
lb_alphakey = Label(fr_labels, text="Alphabet Key:")
lb_keyword.pack(anchor="e"); lb_alphakey.pack(anchor="e")
en_keyword = Entry(fr_entries, width=40,
textvariable=self.sv_keyword)
en_alphakey = Entry(fr_entries, width=40,
textvariable=self.sv_alphakey)
en_keyword.pack(); en_alphakey.pack()
# Make the 'Encipher' and 'Decipher' Buttons
bt_encipher = Button(fr_buttons, text="Encipher",
command=self.encipher)
bt_decipher = Button(fr_buttons, text="Decipher",
command=self.decipher)
bt_encipher.pack(side=LEFT); bt_decipher.pack(side=LEFT)
# Callback which wraps the encipher function
def encipher(self):
# Grab the message, the keyword, and the alphakey
message = self.sv_message.get()
keyword = self.sv_keyword.get()
alphakey = self.sv_alphakey.get()
# If anything is missing, popup an error dialog
# Otherwise, replace the current message with the
# enciphered message
if len(message) == 0 or len(keyword) == 0 or len(alphakey) == 0:
self.popError(message, keyword, alphakey)
else:
self.en_message.delete(0, END)
self.en_message.insert(END,
encipher(message, keyword, alphakey))
# Callback which wraps the decipher function
def decipher(self):
# Grab the message, the keyword, and the alphakey
message = self.sv_message.get()
keyword = self.sv_keyword.get()
alphakey = self.sv_alphakey.get()
# If anything is missing, popup an error dialog
# Otherwise, replace the current message with the
# deciphered message
if len(message) == 0 or len(keyword) == 0 or len(alphakey) == 0:
self.popError(message, keyword, alphakey)
else:
self.en_message.delete(0, END)
self.en_message.insert(END,
decipher(message, keyword, alphakey))
# Popup a dialog which informs the user not to leave fields blank
def popError(self, message, keyword, alphakey):
error = "These boxes can't be left blank:\n"
if len(message) == 0: error = error+"Text or Ciphertext, "
if len(keyword) == 0: error = error+"Keyword, "
if len(alphakey) == 0: error = error+"Alphakey, "
error = error[0:len(error)-2]
tkMessageBox.showerror(title="Error", message=error)
# -- Module functions
# -- Encipher a text using keyword and alphakey
def encipher(text, keyword, alphakey):
# Clean up the text, keyword, and alphakey
text, keyword, alphakey = clean(text, keyword, alphakey)
# Build the major alphabet and the cipher alphabets
major = makeMajor(keyword)
ciphers = makeCiphers(major, alphakey)
# For each character in text, add the substitution character to
# the ciphertext
ciphertext = ""
for i in range(len(text)):
cipher = ciphers[i%len(alphakey)]
substitute = cipher[string.find(major, text[i])]
ciphertext = ciphertext+substitute
return ciphertext
# -- Decipher a text using keyword and alphakey
def decipher(ciphertext, keyword, alphakey):
# Clean up the text, keyword, and alphakey
ciphertext, keyword, alphakey = clean(ciphertext, keyword,
alphakey)
# Build the major alphabet and the cipher alphabets
major = makeMajor(keyword)
ciphers = makeCiphers(major, alphakey)
# For each character in ciphertext, add the correct character to
# the text
text = ""
for i in range(len(ciphertext)):
cipher = ciphers[i%len(alphakey)]
correct = major[string.find(cipher, ciphertext[i])]
text = text+correct
return text
# -- Clean up the text, keyword, and alphakey
def clean(text, keyword, alphakey):
# Get rid of quotes
text = text.replace("\"", "").replace("\'", "")
keyword = keyword.replace("\"", "").replace("\'", "")
alphakey = alphakey.replace("\"", "").replace("\'", "")
# Remove redunant characters from the keyword and alphakey
keyword, alphakey = collapse(keyword), collapse(alphakey)
# Return all three strings
return text, keyword, alphakey
# -- Remove all duplicate letters from keys
def collapse(key):
ret = ""
for i in range(len(key)):
letter = key[i]
duplicate = False
for j in range(i+1, len(key)):
if letter == key[j]: duplicate = True
if not duplicate: ret = ret+letter
return ret
# -- Build the major cipher alphabet around the input keyword
def makeMajor(keyword):
ret = keyword
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"+ \
":.;,?!@#$%&()+=-*/_<> []{}`~^"+ \
"abcdefghijklmnopqrstuvwxyz"
for i in range(len(alphabet)):
if not alphabet[i] in ret: ret = ret+alphabet[i]
return ret
# -- Build the cipher alphabets using the major alphabet and alphakey
def makeCiphers(major, alphakey):
ret = []
for i in range(len(alphakey)):
index = string.index(major, alphakey[i])
ret.append(major[index:]+major[:index])
return ret
# -- Main function
def main(args):
root = Tk()
v = Vigenere(root)
root.mainloop()
# -- The following code executes upon command-line invocation
if __name__ == "__main__": main(sys.argv)