Last active
August 29, 2015 14:22
-
-
Save ryonsherman/0792f8ef03424e12c132 to your computer and use it in GitHub Desktop.
Binary diff + yEnc encoding
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
% ./usenetpatch.py --help | |
usage: usenetpatch.py [-h] {diff,patch} ... | |
positional arguments: | |
{diff,patch} mode | |
diff diff mode | |
patch patch mode | |
optional arguments: | |
-h, --help show this help message and exit | |
% md5sum a.png | |
2c953dc7ba29ecd119f05bd97d4ef584 a.png | |
% md5sum b.png | |
c1576f1ee3b7ea5569707bd4e732fc9c b.png | |
% ./usenetpatch.py diff a.png b.png c.patch | |
Writing 365666 bytes to c.patch - crc32: 9d30f5cb | |
% ./usenetpatch.py patch a.png c.patch c.png | |
Writing 370128 bytes to c.png | |
% md5sum c.png | |
c1576f1ee3b7ea5569707bd4e732fc9c c.png |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
import os | |
import io | |
import yenc | |
import bsdiff4 | |
import argparse | |
# define 'diff' method | |
def diff(file_1, file_2): | |
file_1 = bytes(open(file_1, 'rb').read()) | |
file_2 = bytes(open(file_2, 'rb').read()) | |
diff = io.BytesIO(bsdiff4.diff(file_1, file_2)) | |
patch = io.BytesIO() | |
size, crc = yenc.encode(diff, patch) | |
patch.seek(0) | |
return patch, size, crc | |
# define 'patch' method | |
def patch(file_1, file_2, crc=None): | |
file_1 = bytes(open(file_1, 'rb').read()) | |
patch = io.BytesIO() | |
yenc.decode(open(args.patch, 'rb'), patch, crc_in=crc) | |
patch.seek(0) | |
patch = bytes(patch.read()) | |
file_2 = bsdiff4.patch(file_1, patch) | |
return file_2, len(file_2) | |
# initialize argument parser | |
parser = argparse.ArgumentParser() | |
# initialize 'mode' argument parser | |
subparsers = parser.add_subparsers(dest='mode', help='mode') | |
# initialize 'diff' mode parser | |
diff_parser = subparsers.add_parser('diff', help='diff mode') | |
diff_parser.add_argument('file_1', help='original file') | |
diff_parser.add_argument('file_2', help='modified file') | |
diff_parser.add_argument('patch', help='patch file') | |
# initialize 'patch' mode parser | |
patch_parser = subparsers.add_parser('patch', help='patch mode') | |
patch_parser.add_argument('file_1', help='original file') | |
patch_parser.add_argument('patch', help='patch file') | |
patch_parser.add_argument('file_2', help='modified file') | |
patch_parser.add_argument('--crc', help='crc checksum') | |
# parse arguments | |
args = parser.parse_args() | |
# perform 'diff' method | |
if args.mode == 'diff': | |
patch, size, crc = diff(args.file_1, args.file_2) | |
with open(args.patch, 'wb') as f: | |
f.write(patch.read()) | |
print("Writing %s bytes to %s - crc32: %s" % (size, args.patch, crc)) | |
# perform 'patch' method | |
elif args.mode == 'patch': | |
diff, size = patch(args.file_1, args.patch, args.crc) | |
with open(args.file_2, 'wb') as f: | |
f.write(diff) | |
print("Writing %s bytes to %s" % (size, args.file_2)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment