1

I was recently given a Python script to decrypt Excel files with. I do not have any prior experience working with Python, so I've just been trying to figure out how to run the script correctly through Google searches, but I've hit a wall. From what I can tell, the script is a few years old and might not be up-to-date for Python3.

from StringIO import StringIO
import os
import tkFileDialog

def crypt(t, k):
    old = StringIO(t)
    new = StringIO(t)
    
    for position in xrange(len(t)):
        bias = ord(k[position % len(k)])
        
        old_char = ord(old.read(1))
        new_char = chr(old_char ^ bias)
        
        new.seek(position)
        new.write(new_char)
    
    new.seek(0)
    return new.read()


dirname = tkFileDialog.askdirectory(initialdir="/",  title='Please select a directory')
files = [f for f in os.listdir(dirname) if os.path.join(dirname, f)]
for f in files:
    t = os.path.join(dirname, f)
    tout = os.path.join(dirname, 'decr_%s' % f)
    
    f_in = open(t, 'rb')
    f_out = open(tout, 'wb')
    key = "b8,xaA3rvXb-d&w8P6!9k7dQs.dbkLEw?t!3!`sM(,f!2^6h"
    f_out.write(crypt(f_in.read(), key))
    f_in.close()
    f_out.close()

This is the script I was first given. I tried to make changes after a few ModuleNotFoundErrors and AttributeErrors. Now, the errors coming up are:

Traceback (most recent call last):
  File "/Users/xxx/Desktop/App/Decrypt.py", line 34, in <module>
    f_out.write(crypt(f_in.read(), key))
  File "/Users/xxx/Desktop/App/Decrypt.py", line 9, in crypt
    old = StringIO(t)
TypeError: initial_value must be str or None, not bytes

Not sure how to work with this error – would appreciate any help or advice!

Eunice G.
  • 11
  • 2

2 Answers2

0

f_in.read() reads bytes from a file, and StringIO can't deal with a bytes value as initial value. You can convert your bytes variable to a str variable and use that in the StringIO constructor.

See also:Convert bytes to a string

0

The file.open() function has the 'rb' argument, which specifies that it will read the contents of the file as bytes.

In order to convert the bytes to string, so that the other function can be used, you have two options:

  • Use the decode("utf-8") function. Be careful that the encoding of the data you are using is indeed utf-8 though, otherwise specify the one your data are using.
    Your line should be: f_out.write(crypt(f_in.read().decode("utf-8"), key)).
  • If you are sure that the file contains only text, you can omit the 'b' argument and use only f_in = open(t, 'r'). This will open and read the file in text mode, meaning you can read things directly as strings.

Also, considering the above, be careful of how you write the contents to the output file (either as bytes, or string).

liakoyras
  • 1,101
  • 12
  • 27
  • If you feel like this answers your question, please consider accepting the answer and upvoting it in order for future users to be able to find it easier. – liakoyras Nov 24 '20 at 07:25