Skip to content

Commit

Permalink
#5 add python script for csv decoding
Browse files Browse the repository at this point in the history
  • Loading branch information
Serphentas committed May 26, 2019
1 parent da6a779 commit 9ad0024
Showing 1 changed file with 128 additions and 0 deletions.
128 changes: 128 additions & 0 deletions xtRLE.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import argparse, os

XTRLE_MAGIC = 'xtRLE'
KEY_ONE = 0xA5
KEY_TWO = 0x00

def bytes_to_int(arr):
size = len(arr)
res = 0
for i in range(0, 4):
res |= (int(arr[i]) << ((size - 1 - i) * 8))
return res

def decompress(file):
magic = file.read(len(XTRLE_MAGIC))
if magic.decode('ascii') != XTRLE_MAGIC:
file.close()
raise ValueError('Infile is not encoded with {}'.format(XTRLE_MAGIC))

# skip magic end (0x00)
file.read(1)
# unknown value
file.read(4)

# recover size
size = bytes_to_int(file.read(4)[::-1])

data = [0] * size
data_ptr = 0

c = file.read(1)
while c and c[0] != 0x0:
if c[0] == 0x0:
file.seek(0x0E + num)
else:
num = c[0] & 0x7F

if c[0] & 0x80:
# read whole num-chunk from file
new_data = file.read(num)
if not new_data:
file.close()
raise ValueError('Error reading input file')
else:
for i in range(0, num):
data[data_ptr + i] = new_data[i]
else:
# copy next byte num-times
c = file.read(1)
if c[0] == 0x0:
file.close()
raise ValueError('Error reading input file')
for i in range(0, num):
data[data_ptr + i] = c[0]

data_ptr += num
c = file.read(1)

return data, size

def decrypt(data, size):
if not size:
return

res = data.copy()
c = data[0]
i = 1

while True:
d = res[i]
if d == c:
while i < size:
d = res[i]
res[i - 1] = c ^ KEY_TWO
if d != c:
break
i += 1
else:
res[i - 1] = c ^ KEY_ONE

if i >= size - 1:
res[size - 1] = d ^ (KEY_TWO if c == d else KEY_ONE)
break

c = d
i += 1

return res

def run(key1, key2, infile, outfile):
if infile == outfile:
raise ValueError('Input and output files are the same')

if not os.path.exists(infile):
raise FileNotFoundError("Input file does not exist")
f_in = open(infile, 'rb')

if not outfile:
outfile = './' + infile.split('.')[0][::-1].split('/')[0][::-1] + '.csv'
print('Output not given, using {}'.format(outfile))
f_out = open(outfile, 'w')
else:
if os.path.exists(outfile):
os.remove(outfile)
print('Overwriting {}'.format(outfile))
f_out = open(outfile, 'w')

data, size = decompress(f_in)
if not data:
raise ValueError('Decompressed file appears to be empty')

res = decrypt(data, size)
for x in res:
f_out.write(chr(x))

f_in.close()
f_out.close()

if __name__ == "__main__":
parser = argparse.ArgumentParser(description="xtRLE decoder")
parser.add_argument('--key1', '-k1', type=int, required=False, help='Key 1')
parser.add_argument('--key2', '-k2', type=int, required=False, help='Key 2')
parser.add_argument('--infile', '-i', type=str, required=True, help='Input file')
parser.add_argument('--outfile', '-o', type=str, required=False, help='Output file')
args = parser.parse_args()

run(args.key1, args.key2, args.infile, args.outfile)

1 comment on commit 9ad0024

@Serphentas
Copy link
Collaborator Author

@Serphentas Serphentas commented on 9ad0024 May 26, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just a Python3 rewrite of xtRLE_dec.c, so it may serve for an implementation in C# later.

Please sign in to comment.