Encrypting a Text File in Python, Preferably with a Module

3.3k Views Asked by At

Context:

I have a class, in which I have to make a password protected something or other.
(My instructor is not very specific.) The reason for me asking for a method in which I could use a standard import statement was so I could just upload a single folder that only contained a text file and the program itself. I want to do something as follows:

#Import Statements Here
outFile = open('myFile.txt',"wt");

#Here is the tricky part.
#In place of all of these comments,
#I want to encrypt the file with a key given by a user(in this case,givenKey):
givenKey = input("Please input your key:>>>");
outFile.close();

Resolution:

The answer by Sasszem was the one that worked for me. Look into the comments for a simplified explanation of the main answer. The person who gave me his/her custom made code (I cant remember who gave it to me, sorry.) had a good idea. But I don't like using code I don't understand. And finally, the person who gave me the Cryptography module as an idea wasn't wrong, but I use python on Windows.

3

There are 3 best solutions below

6
On BEST ANSWER

A simple way to encrypt data is to add a constant to every byte.

You can generate some random byte from the pwd and then add it to every byte in the input. It won't be strong, but it's simple.

If you make something like your program generates random numbers to add to the bytes after seeding your pwd to the random generator, your instructor will be impressed.

To decode, simply subtract the same numbers from the bytes.

2
On

Here is a module I wrote a while back. It uses only built-in python modules. I give you permission to use it!

import string, random

class Round(object):
    def __init__(self, *seqs):
        self.position = 0
        self.data = [i for x in seqs for i in x]
        self.len = len(self.data)

    def __repr__(self):
        return str(self.data)

    def __iter__(self):
        self.position = 0
        return self

    def is_item(self, item):
        if str(self.data[self.position]) == str(item):
            return True
        return False

    def __getitem__(self, index):
        if index < self.len-1 and index >= 0:
            return self.data[index]
        else:
            while index < 0:
                index += self.len-1
            while index > self.len-1:
                index -= self.len-1
            return self.data[index]

    def next(self):
        if self.position >= self.len-1:
            self.position = 0
            raise StopIteration
        else:
            self.position += 1
            return self.data[self.position-1]

class JCripter(object):
    def __init__(self, string):
        self.string = string
        self.generate_key_set()
        self.encrypted = False

    def generate_key_set(self):
        self.alphabet = list(string.ascii_lowercase)
        self.numbers = [str(x) for x in range(10)]
        self.special_characters = ['"',"'",',','?','.',
                                   ' ','(',')',':',';',
                                   '!','@','#','$','%',
                                   '^','&','*','_','-',
                                   '+','=','<','>','~',
                                   '`','{','[','}',']',
                                   '\\','|']
        self.key_base = Round(self.alphabet, self.numbers, self.special_characters)

    def get_key_index(self, key):
        for i in self.key_base:
            if isinstance(key, int):
                if i == self.key_base[key]:
                    return self.key_base.position-1
            elif i == key.lower():
                return self.key_base.position-1
        else:
            print 'not found'

    def __repr__(self):
        return self.string

    def _encrypt(self, string, func, *args):
        if string == None:
            string = self.string
            if string == None:
                return
        string = string.lower()
        n_string = func(string, *args)
        self.encrypted = not self.encrypted
        self.string = n_string
        return n_string

class CeaserCypher(JCripter):
    def __init__(self, string, shift=None):
        JCripter.__init__(self, string)
        if shift == None:
            self.shift = random.randint(0, self.key_base.len)
        else:
            self.shift = shift

    def encrypt(self, string=None):
        def inner(string):
            n_string=''
            for i in string:
                if self.encrypted == True:
                    n_string += self.key_base[self.get_key_index(i)-self.shift]
                else:
                    n_string += self.key_base[self.get_key_index(i)+self.shift]
            return n_string
        return self._encrypt(string, inner)

class PseudoRandomCypher(JCripter):
    def __init__(self, string, shifts=None):
        if shifts == None:
            self.shift = [random.randint(0, 500) for x in string]
        else:
            self.shift = shifts
        JCripter.__init__(self, string)

    def encrypt(self, string=None):
        def inner(string):
            ind = 0
            n_string = ''
            for i in string:
                if ind >= len(self.shift)-1:
                    ind = 0
                if self.encrypted == True:
                    n_string += self.key_base[self.get_key_index(i)-self.shift[ind]]
                else:
                    n_string += self.key_base[self.get_key_index(i)+self.shift[ind]]
                ind += 1
            return n_string

        return self._encrypt(string, inner)

class PolyAlphabeticCypher(JCripter):
    def __init__(self, string, key, enc=False):
        JCripter.__init__(self, string)
        self.key=list(key)
        self.encrypted = enc

    def encrypt(self, string=None):
        def inner(string):
            index = 0
            n_string = ''
            for i in string:
                if index >= len(self.key)-1:
                    index = 0
                if self.encrypted == True:
                    n_string += self.key_base[self.get_key_index(i)-self.get_key_index(self.key[index])]
                else:
                    n_string += self.key_base[self.get_key_index(i)+self.get_key_index(self.key[index])]
                index += 1
            return n_string
        return self._encrypt(string, inner)


n = 'Hello world my name is anonymous!'
p = PolyAlphabeticCypher(n, 'super_secret_password')
print p.encrypt() #--> returns encrypted data
print p.encrypt() #--> decrypts data


#if you are decrypting a previously encrypted text

n = 'Some sensitive data'
first = PolyAlphabeticCypher(n, 'some pass')
my_data = first.encrypt()
second = PolyAlphabeticCypher(my_data, 'some pass', True)
print second.encrypt()
1
On

Package cryptography provides support for encryption/decryption: https://pypi.python.org/pypi/cryptography. I understand that it is included in Anaconda.