Skip to content

Instantly share code, notes, and snippets.

@udgover
Created June 2, 2020 11:44
Show Gist options
  • Save udgover/35857a6ff9ceff4e16db9691df428669 to your computer and use it in GitHub Desktop.
Save udgover/35857a6ff9ceff4e16db9691df428669 to your computer and use it in GitHub Desktop.
Examples to deal with PyEasyArchive encrypted archives reading and writing
import libarchive.public
import libarchive.constants
import libarchive.adapters.archive_read
import hashlib
import os
import shutil
# from https://stackoverflow.com/a/1094933
def sizeof_fmt(num, suffix='B'):
for unit in ['','Ki','Mi','Gi','Ti','Pi','Ei','Zi']:
if abs(num) < 1024.0:
return "%3.1f%s%s" % (num, unit, suffix)
num /= 1024.0
return "%.1f%s%s" % (num, 'Yi', suffix)
def create_archive(destination, files, options, passphrase=None):
a = libarchive.public.create_file(destination,
libarchive.constants.ARCHIVE_FORMAT_ZIP,
files, passphrase=passphrase, options=options)
if len(a) != len(files):
print(len(a), len(files))
missing = set(files) - set(a)
print("The following files were not added to archive:")
for missing_file in missing:
print(missing_file)
def extract_file(entry, destination):
m = hashlib.sha256()
filename = os.path.basename(entry.pathname)
extracted_file = os.path.join(destination, filename)
if not os.path.exists(destination):
os.makedirs(destination)
print("Extracting: {src} --> {dest}".format(src=entry.pathname,
dest=extracted_file))
with open(extracted_file, "w+b") as f:
for block in entry.get_blocks():
f.write(block)
m.update(block)
print("\tUncompressed size: {size}".format(size=sizeof_fmt(entry.size)))
print("\tSHA256: {}".format(m.hexdigest()))
def extract_folder(entry, destination):
if not os.path.exists(destination):
print("Creating folder: {}".format(destination))
os.makedirs(destination)
else:
print("Folder already exists (skipping): {}".format(destination))
def extract_archive(archive, destination, passphrases=None):
destination = os.path.abspath(destination)
if not os.path.exists(destination):
os.makedirs(destination)
with libarchive.adapters.archive_read.file_enumerator(archive, passphrases=passphrases) as e:
for entry in e:
pathname = os.path.dirname(entry.pathname)
abspath = os.path.join(destination, pathname)
if entry.filetype.IFDIR:
extract_folder(entry, abspath)
else:
extract_file(entry, abspath)
if __name__ == "__main__":
option = True
if option:
options = "zip:encryption=aes256"
#options = "zip:encryption=traditional"
else:
options= ""
files = [
'libarchive/resources/README.md',
'libarchive/resources/requirements.txt',
'/tmp/empty_folder'
]
create_archive("/tmp/test42.zip", files, options, passphrase="test42")
extract_archive("/tmp/test42.zip", "/tmp/extract", passphrases=["test42"])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment