samedi 25 juillet 2015

Randomized Vigenere Cipher with Python

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.

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 most 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:
#string containing all valid characters
symbols= """ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"""
matrix = []

#Generate psuedorandom keyword from seed
def keywordFromSeed(seed):
    Letters = []

    while seed > 0:
        Letters.insert(0,chr((seed % 100) % 26 + 65))
        seed = seed // 100
    return ''.join(Letters)

#Contructs a 95 x 95 matrix filled randomly
def buildVigenere():
    n = len(Vigenere.symbols)
    print(n)
    vigenere = [[0 for i in range(n)] for i in range(n)]

    #Build the vigenere matrix
    for i in range(n):
        temp = Vigenere.symbols

        for j in range(n):
            r = random.randrange(len(temp))
            vigenere[i][j] = temp[r]
            temp = temp.replace(temp[r],'')

    Vigenere.matrix = vigenere
    return vigenere

def encrypt(plaintext,keyword):
    ciphertext = ""
    for i in range(len(plaintext)):
        mi = i
        ki = i % len(keyword)
        ciphertext = ciphertext + Vigenere.eRetrieve(Vigenere.matrix,keyword,plaintext,ki,mi)
    return ciphertext

def decrypt(ciphertext,keyword):
    plaintext = ""
    for i in range(len(ciphertext)):
        emi = i
        ki = i % len(keyword)
        plaintext = plaintext + Vigenere.dRetrieve(Vigenere.matrix,keyword,ciphertext,ki,emi)
    print(plaintext)

def eRetrieve(v,k,m,ki,mi):       
    row = ord(m[mi]) - 32
    col = ord(k[ki]) - 32
    return v[row][col]

def dRetrieve(v,k,em,ki,emi):
    n = len(Vigenere.symbols)
    whichRow = ord(k[ki]) - 32
    for i in range(n):
        if v[whichRow][i] == em[emi]:
            print(i, chr(i))
            decryptChar = chr(i + 32)
            print(decryptChar)
            return(decryptChar)

And just in case it helps, here's my main.py:

import argparse
import randomized_vigenere as rv
import random

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
random.seed(seed)
keyWord = rv.Vigenere.keywordFromSeed(seed)
print(keyWord)

#Construct Matrix
vigenere = rv.Vigenere.buildVigenere()
print(vigenere)

f = open(args.inputFile,'r')
message = f.read()

if(args.mode == 'encrypt'):
    cipher = ""
    data = rv.Vigenere.encrypt(message,keyWord)
    print(data)
    cipher = rv.Vigenere.decrypt(data,keyWord)
    print(cipher)
else:
    data = rv.Vigenere.decrypt(message,keyWord)

o = open(args.outputFile,'w')
o.write(str(data))

if __name__ == '__main__':
    main()

I've just been using the default seed (7487383487438734)

My Plaintext: ABCdefXYZ

What I get as Ciphertext: $[iQ#`CzK

What I recieve after decryption: !TWu.Ck[b

My thoughts are that the error lies somewhere with my matrix generation. But unfortunately, I'm stumped. Any help would very much be appreciated!




Aucun commentaire:

Enregistrer un commentaire