# Modification of Vigenere en/deciphering algorithm

0 Tallied Votes 219 Views

Here's a cute little encipher/decipher program with a Tkinter GUI I wrote a while back. It's an implementation of a derivative of the Vigenere algorithm; the algorithm is taken from Laurence Smith's Cryptography: The Science of Secret Writing, Amazon link here. It's a dated book (and the technique itself is very old), so don't expect any serious security from this - just something fun to think about.

For a fairly complete description of how it works, see this post:
http://daniweb.com/techtalkforums/post155767-1.html

NOTE: Apparently, the CGI that controls "contribution" submissions inserts newlines around comments, leaving the code looking very sparse. I think it looks ugly. For a more compact version of the same, see the original post.

``````# 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)``````
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.