Xit/commands.py

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()