Xit/commands.py
Christophe HENRY 3d71aa2e6f
Xit is a Python program that applies XOR to files
It's not designed to be used for cryptographic stuff, unless you know what
you're doing or you want to hide from your little sister. Xit processes files
in the memory and is not designed to treat huge data.
2018-12-06 23:47:04 +01:00

62 lines
2.4 KiB
Python

#!/usr/bin/python3
import os, re, sys, random, hashlib
import sys
import lib_xit
""" Contains the commands available through the command line """
def xorFiles(keyStrings, inFileNames, outFileNames, outSha1Files, size):
""" XOR(inFileNames) == XOR(outFileNames)
The size is the size of all output files. If necessary it pads or truncate files.
"""
keyStrings = [bytearray(k, 'utf8') for k in keyStrings]
try:
inFiles = [open(fileName, 'rb') for fileName in inFileNames]
inSizes = [len(k) for k in keyStrings] + [os.fstat(f.fileno()).st_size for f in inFiles]
if size =="min": size = min(inSizes)
elif size =="max": size = -1
elif size =="first": size = inSizes[0]
elif size == "last": size = inSizes[-1]
elif size == "even":
if len(set(inSizes))!=1:
# Security check, better stop here than truncating data!
raise IndexError('ERROR: check --size and file sizes!')
size = -1
assert(type(size) is int)
# The smaller data will be looped in XorData
inContents = keyStrings + [bytearray(f.read(size)) for f in inFiles]
outContents = lib_xit.xorData(inContents, len(outFileNames) + (1 if outSha1Files else 0), size)
for fileName in outFileNames:
with open(fileName, "wb") as f:
f.write(outContents.pop())
assert(len(outContents) == bool(outSha1Files)) # There must be a last one to build the sha1
if outSha1Files:
allSha1Xor = outContents.pop() # All sha1 sequences share the same XOR
assert(not outContents) # It was the last one, added to get the XOR of sha1 sets
for outSha1File in outSha1Files: # One XOR set for each sha1 file name
outContents = lib_xit.xorData(allSha1Xor, int(outSha1File), size)
filesAndContents = []
for _ in range(int(outSha1File)):
content = outContents.pop()
sha1 = hashlib.sha1(content).hexdigest()
filesAndContents.append((outSha1File.nameWithSha1(sha1), content))
assert(not outContents) # All the contents to be written, no more no less
for fileName, content in filesAndContents:
with open(fileName, 'wb') as f:
f.write(content)
finally:
for i in inFiles: i.close()