65 lines
1.9 KiB
Python
65 lines
1.9 KiB
Python
#!/bin/python3
|
|
|
|
import argparse
|
|
import hashlib
|
|
import os
|
|
import shutil
|
|
import struct
|
|
|
|
|
|
def gen_cascade_file(sourcefile, targetfile, cascade_file, blocksize):
|
|
with open(sourcefile, 'rb') as src:
|
|
# Place entire file in memory :)
|
|
data = src.read()
|
|
fullsize = len(data)
|
|
fullhash = hashlib.sha256(data).digest()
|
|
|
|
with open(cascade_file, 'wb') as dst:
|
|
# Header part
|
|
dst.write(bytes('CASCADE1', 'ascii')) # Magic signature
|
|
dst.write(struct.pack('!Q', 0)) # Reserved
|
|
dst.write(struct.pack('!Q', fullsize)) # File length
|
|
dst.write(struct.pack('!Q', blocksize)) # Block size
|
|
dst.write(fullhash)
|
|
|
|
with open(sourcefile, 'rb') as src:
|
|
while True:
|
|
data = src.read(blocksize)
|
|
if not data:
|
|
break
|
|
dst.write(hashlib.sha256(data).digest())
|
|
|
|
if not os.path.exists(targetfile):
|
|
shutil.copy(sourcefile, targetfile)
|
|
|
|
blocksizes = [
|
|
(1024, '1kib'),
|
|
(10240, '10kib'),
|
|
(102400, '100kib'),
|
|
(1048576, '1mib'),
|
|
(10485760, '10mib')
|
|
]
|
|
|
|
if __name__ == "__main__":
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("source", help="The file to generate the cascade file for")
|
|
args = parser.parse_args()
|
|
|
|
sourcefile = os.path.abspath(args.source)
|
|
if not os.path.isfile(sourcefile):
|
|
print(f"Source file not found: {sourcefile}")
|
|
exit(1)
|
|
|
|
for bs in blocksizes:
|
|
basename, ext = os.path.splitext(sourcefile)
|
|
targetfile = f"{basename}.{bs[1]}{ext}"
|
|
cascade_file = f"{targetfile}.cascade"
|
|
if os.path.isfile(targetfile):
|
|
print(f"File already exists, deleting: {targetfile}")
|
|
os.unlink(targetfile)
|
|
|
|
print(f"Generating file: {targetfile}")
|
|
gen_cascade_file(sourcefile, targetfile, cascade_file, bs[0])
|
|
|
|
print("Done!")
|