To clarify before beginning: I'm aware there are similar topics, but nothing that has really offered any direct help. Also: this is a class project; so I'm not looking for anyone to code my project for me. Tips and advice is what I'm looking for. (I would go to my professor for this kind of thing, but he can't be bothered to check his e-mail.)
This program is meant to take a user supplied seed, generate a key based on the integer, then to generate a 95 x 95 matrix in which all printable ascii characters are available for encryption/decryption purposes. (Key is all alpha, and capitalized)
The kicker: all the cells must be randomized. See image below: Randomized Vigenere Matrix
I will post my code below (Python is certainly not my forte, though I will definitely take constructive criticisms.):
import random
class Vigenere(object):
def __init__(self, seed):
random.seed(seed)
#string containing all valid characters
self.symbols= """!"#$%&'()*+,-./0123456789:;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\] ^_`abcdefghijklmnopqrstuvwxyz{|}~"""
self.eTable = [[0 for i in range(len(self.symbols))] for i in range(len(self.symbols))]
self.dTable = [[0 for i in range(len(self.symbols))] for i in range(len(self.symbols))]
self.keyWord = ""
self.message = ""
self.ciphertext = ""
self.keywordFromSeed(seed)
def setMessage(self,message):
self.message = message
#Generate psuedorandom keyword from seed
def keywordFromSeed(self,seed):
Letters = []
while seed > 0:
Letters.insert(0,chr((seed % 100) % 26 + 65))
seed = seed // 100
self.keyWord = "".join(Letters)
self.buildVigenere()
#Contructs a 95 x 95 matrix filled randomly
def buildVigenere(self):
n = len(self.symbols)
#Build the vigenere matrix
for i in range(n):
temp = self.symbols
for j in range(n):
r = random.randrange(len(temp))
self.eTable[i][j] = temp[r]
#This line below does not fill entire matrix. Why?
self.dTable[j][(ord(temp[r])-32)] = chr(i+32)
temp = temp.replace(temp[r],'')
def encrypt(self):
for i in range(len(self.message)):
mi = i
ki = i % len(self.keyWord)
self.ciphertext = self.ciphertext + self.eRetrieve(ki,mi)
def decrypt(self):
for i in range(len(self.message)):
emi = i
ki = i % len(self.keyWord)
char = self.dRetrieve(ki,emi)
self.ciphertext = self.ciphertext + char
print(self.ciphertext)
def eRetrieve(self,ki,mi):
row = ord(self.message[mi]) - 32
col = ord(self.keyWord[ki]) - 32
print(row, col)
return self.eTable[row][col]
def dRetrieve(self,ki,emi):
n = len(self.symbols)
whichRow = ord(self.keyWord[ki]) - 32
whichCol = ord(self.message[emi]) - 32
return(self.dTable[whichRow][whichCol])
And just in case it helps, here's my main.py:
import argparse
import randomized_vigenere as rv
def main():
#Parse parameters
parser = argparse.ArgumentParser()
parser.add_argument("-m", "--mode", dest="mode", default = "encrypt", help="Encrypt or Decrypt")
parser.add_argument("-i", "--inputfile", dest="inputFile", default = "inputFile.txt", help="Input Name")
parser.add_argument("-o", "--outputfile", dest="outputFile", default = "outputFile.txt", help="Output Name")
parser.add_argument("-s", "--seed", dest="seed", default =7487383487438734, help="Integer seed")
args = parser.parse_args()
#Set seed and generate keyword
seed = args.seed
#Construct Matrix
f = open(args.inputFile,'r')
message = f.read()
Matrix = rv.Vigenere(seed)
Matrix.setMessage(message)
if(args.mode == 'encrypt'):
Matrix.encrypt()
Matrix.setMessage(Matrix.ciphertext)
Matrix.decrypt()
else:
Matrix.decrypt()
o = open(args.outputFile,'w')
o.write(str(Matrix.ciphertext))
if __name__ == '__main__':
main()
I've just been using the default seed: 7487383487438734
My Plaintext: ABCdefXYZ