#!/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()