You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
62 lines
2.4 KiB
Python
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()
|