Christophe HENRY
3d71aa2e6f
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.
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()
|