I appologize for the length of this post, but I have no clue what is wrong with my program. As an experiment, I wrote a XOR encryption program. It isnt very fast, but it works. Apparently, only for strings. I implemented a file encryption function, and it seems that some characters come out slightly different (As in the ord() function returns numbers that are only slightly different). I have tested the same string as contained in the file using the string encoder, and it works fine. Any help is greatly apppriciated. My code is attached below, Along with a couple text files. The unmodified text is in unmodified.txt, the encrypted text is in encrypted.txt, and the decrypted text is in decrypted.txt. There is also errors.txt, which shows which characters are off and by how much. Again, All help is greately appriciated.

from __future__ import division
from math import ceil
def xor_tuple(message, password, type): #XOR a few characters
    len_mess, len_pass = len(message), len(password) 
    if len_mess != len_pass: raise message + ' and ' + password + ' are not same lengths!' #Not same length strings
    result = [] #Empty list for result
    for x in range(0, len_mess, 1): #Cycle through characters and XOR them, then append them to the list
        if type == 'chr': #Outputs characters
            result.append(chr(ord(message[x]) ^ ord(password[x])))
        if type == 'int': #Outputs a list of numbers, the result of ord(char)
            result.append(ord(message[x]) ^ ord(password[x]))
    return result
def crypt(message='message', password='password', type='chr', input=''): #Encrypt/Decrypt function
    #Type - chr returns characters, int returns a list of numbers
    #Input - Leave blank, unless inputting a list of numbers, then change to int
    if type != 'chr' and type != 'int': raise type + " is not a type. Accepted types are 'int' or 'chr'." #Error checking
    if input != 'int' and input != '': raise input + " is not an input. Accepted inputs are 'int' or ''."
    if input ==  'int': #Make sure a list of numbers is passed, and if not, leave it alone
        try:
            message[0] + 1
            temp = ''
            for char in message: temp = temp + chr(char)
            message = temp
        except: pass
    len_mess, len_pass = len(message), len(password)
    passes = int(ceil(len_mess/len_pass)) #How many times the password must be repeated throughout the message
    crypted = [] #Empty list for result
    for x in range(0, passes, 1): #Cylces through the message
        temp = xor_tuple(message[x*len_pass:x*len_pass+len_pass], password[0:len(message[x*len_pass:x*len_pass+len_pass])], type)
        for item in temp: #Appends every number individually
            crypted.append(item)
    if type == 'int': return crypted
    crypted2 = ''
    for char in crypted: crypted2 = crypted2 + char
    return crypted2
def crypt_file(filename, password): #Password is a string, filename is a file
    if filename[len(filename)-9:len(filename)] == 'encrypted': #We are decrypting
        infile = open(filename, 'U') #Open the encrypted file
        outfile = open(filename[:len(filename)-10], 'wb') #Create the decrypted file without the .encrypted suffix
    else: #We are encrypting
        infile = open(filename, 'U') #Open the unencrypted file
        outfile = open(filename+'.encrypted', 'wb') #Create the encrypted file
    infile_data = '' #Everything else remains the same
    for char in infile: infile_data = infile_data + char #Dump the data of the file to a string
    outfile.write(crypt(infile_data, password, 'chr')) #Actual encrypting/decrypting
    infile.close() #Close the files
    outfile.close()

Recommended Answers

All 3 Replies

hi,

i did write a XOR encrypt/decrypt program too few days ago inspired from a post from this forum, and i encounter almost the same problem with you. i dont know which python version you are using, but i was using python 3.1.

i dont know whether your solution will be the same as mine, but at my problem, the error was in the file encoding, since writing to a text file will default to ascii encoding, and since my encryption would result in character with higher than ascii code 255 (i was using unicode), i have to specify the correct encoding.

here is a snippet of my correct code:

def encryptfile(filename):
    f = open(filename, 'r')
    plain = f.read()
    f.close()

    ciphertext = encrypttext(plain)

    # Change file extension for encrypted file
    if filename.endswith('.txt'):
        outfile = filename[:-4] + '.txc'

    f = open(outfile, encoding = 'utf-8', mode='w+')
    f.write(ciphertext)
    f.close()
    print("File '%s' is encrypted to '%s'" % (filename,outfile))

def decryptfile(filename):
    f = open(filename, encoding='utf-8', mode='r')
    cipher = f.read()
    f.close()

    plain = decrypttext(cipher)

    if filename.endswith('.txc'):
        outfile = filename[:-4] + '.txt'

    f = open(outfile, mode='w')
    f.write(plain)
    f.close()
    print("File '%s' is decrypted as '%s'" % (filename, outfile))

if you are not using python 3.1, then perhaps you have to change the syntax. perhaps your problem is the same as mine. i hope with this your problem is solved.

I am using python 2.5.4, and I don't think that I can specify encoding. When I try to, it gives me the following error: " 'encoding' is an invalid keyword arguement for this function". I will look through the documentation to see if I can change the encoding. Thanks for the help.

Edit: I don't think 2.5.4 allows the encoding to be specified.

I got it. I changed the read mode from 'U' to 'rb'. Odd, but it works. Thanks for your help everyone.

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.