From 73723e5a9f224377ef64f013875a44d64811007b Mon Sep 17 00:00:00 2001 From: Daylin Morgan Date: Wed, 31 Jul 2024 15:05:10 -0500 Subject: [PATCH] add script to make datamatrix key backup --- bin/gpg-key-to-datamatrix | 63 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100755 bin/gpg-key-to-datamatrix diff --git a/bin/gpg-key-to-datamatrix b/bin/gpg-key-to-datamatrix new file mode 100755 index 0000000..d1d5c44 --- /dev/null +++ b/bin/gpg-key-to-datamatrix @@ -0,0 +1,63 @@ +#! /usr/bin/env nix-shell +#! nix-shell -p typst dmtx-utils -i python + +import subprocess +import argparse +import shlex +import tempfile +from pathlib import Path +from math import ceil + + +def sub(cmd: str, *args, **kwargs): + return subprocess.check_output(shlex.split(cmd), *args, **kwargs) + + +def typst_file_tmpl(files): + local_paths = [f.relative_to(Path.cwd()) for f in files] + return "\n".join(f'#image("{f}")' for f in local_paths) + + +def chunk_key(key): + """ + split byte string into even chunks + chunks will be <= 1555 bytes in length since + 1555 is the maxiumum byte size for datamatrix + """ + n = ceil(len(key) / ceil(len(key) / 1555)) + return [key[i : i + n] for i in range(0, len(key), n)] + + +def generate_pdf(byte_chunks, svgpath, outpath): + for f, data in zip( + files := [svgpath / f"dmtx-{i}.svg" for i, _ in enumerate(byte_chunks)], + byte_chunks, + ): + sub(f"dmtxwrite -e 8 -o {f}", input=data) + sub(f"typst compile - {outpath}", input=typst_file_tmpl(files), text=True) + + +def get_key_data(key): + suffix = key if key else "" + return chunk_key( + sub(f"gpg --export-secret-key --export-options export-minimal {suffix}") + ) + + +def main(): + p = argparse.ArgumentParser() + p.add_argument("--key", help="key id") + p.add_argument( + "--output", help="pdf to write matrices to", default=Path.cwd() / "key.pdf" + ) + + args = p.parse_args() + byte_chunks = get_key_data(args.key) + + with tempfile.TemporaryDirectory(dir=Path.cwd()) as tmpdirname: + tmpdir = Path(tmpdirname) + generate_pdf(byte_chunks, tmpdir, args.output) + + +if __name__ == "__main__": + main()