-1

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.

Community
  • 1
  • 1
Riggycat
  • 41
  • 1
  • 4
  • I don't think that the Python standard library has the features you want (yet). You'll need some third-party library to provide them. – 5gon12eder Dec 31 '16 at 01:54
  • Aside from everything else, in the last line of your snippet you _think_ you close the `outFile`, while, in fact, you don't. – DYZ Dec 31 '16 at 01:54
  • @DYZ Ok, so how do I _not just think but actually close_ my `outFile`? – Riggycat Dec 31 '16 at 01:56
  • 2
    call the close function! `close()` – TheLazyScripter Dec 31 '16 at 01:58
  • 2
    If it's for a class, and the instructor wasn't specific, the encryption strength probably doesn't matter. I doubt it's even supposed to be encrypted. Side note: who taught you to end Python statements with a semicolon? – TigerhawkT3 Dec 31 '16 at 02:09
  • I get a better grade with more features! ;D Side Answer: And the semi-colon thing was back from Processing JS. I just never broke the habit, and never had a reason to stop using them! – Riggycat Dec 31 '16 at 04:26

3 Answers3

0

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

DYZ
  • 55,249
  • 10
  • 64
  • 93
0

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()
TheLazyScripter
  • 2,541
  • 1
  • 10
  • 19
  • This is a really cool concept and all, but my program is for a beginners class. This looks really handy but I am not at the level at which needed to use it (or understand it completely). I think this snippet is longer than my entire program! Anyway, thanks for the help. P.S., I like your username! ;D P.P.S: I wish I could select _two_ answers... – Riggycat Dec 31 '16 at 04:19
  • Have a good one, and good luck! – TheLazyScripter Dec 31 '16 at 04:32
0

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.

jophab
  • 5,356
  • 14
  • 41
  • 60
Uncle Dino
  • 812
  • 1
  • 7
  • 23
  • Ok, this seems like the right answer, but like I said, I am a beginner. Is there a guide that toy can point me to? – Riggycat Dec 31 '16 at 04:29
  • Here's the most simple method: Input a number from the user, that'll be your password. Open the input file in binary mode, open the output in binary mode, read a byte from input, add your value to it and then write it to the output. When done, close both files. – Uncle Dino Dec 31 '16 at 21:23
  • I have to say that I've not tested this in python yet, so maybe there'll be some issues. – Uncle Dino Dec 31 '16 at 21:24
  • I've found my encrypter and uploaded to git. If you want to take a look: https://github.com/Sasszem/encrypter – Uncle Dino Dec 31 '16 at 21:37
  • That... that is SO AWESOME! Thank you SO MUCH! Its so obvious now! It won't mean much, but I will credit you in my program! – Riggycat Jan 01 '17 at 07:19
  • " get a better grade with more features!" I would recommend to use command-line args to specify input and output file, also the pwd. If the args don't match, print help. If the input doesn't exists, give error msg. If the output already exists, war user and create new file... – Uncle Dino Jan 01 '17 at 13:20