# HG changeset patch # User Laman # Date 2017-09-23 15:22:32 # Node ID 9c496886dde98a8a7939ae1da8e39bc528fe2e89 # Parent 3907396d80a5a10a183e06e5dbbc43e402224882 CLI, bugfixes diff --git a/src/cli.py b/src/cli.py new file mode 100644 --- /dev/null +++ b/src/cli.py @@ -0,0 +1,60 @@ +from argparse import ArgumentParser + +from shamira import generate, reconstruct + + +def run(): + parser=ArgumentParser() + subparsers=parser.add_subparsers() + + buildSplitParser(subparsers.add_parser("split")) + buildJoinParser(subparsers.add_parser("join")) + + parser.set_defaults(func=lambda: parser.error("missing command")) + + args=parser.parse_args() + args.func(args) + + +def buildSplitParser(parser): + parser.add_argument("-k",type=int,required=True,help="number of shares necessary for recovering the secret") + parser.add_argument("-n",type=int,required=True,help="number of generated shares") + + encoding=parser.add_mutually_exclusive_group() + encoding.add_argument("--hex",action="store_true",help="encode shares' bytes as a hexadecimal string") + encoding.add_argument("--b32",action="store_true",help="encode shares' bytes as a base32 string") + encoding.add_argument("--b64",action="store_true",help="encode shares' bytes as a base64 string") + + parser.add_argument("secret",help="secret to be parser") + parser.set_defaults(func=_generate) + + +def buildJoinParser(parser): + encoding=parser.add_mutually_exclusive_group() + encoding.add_argument("--hex",action="store_true",help="decode shares' bytes from a hexadecimal string") + encoding.add_argument("--b32",action="store_true",help="decode shares' bytes from a base32 string") + encoding.add_argument("--b64",action="store_true",help="decode shares' bytes from a base64 string") + + parser.add_argument("-r","--raw",action="store_true",help="return secret as raw bytes") + parser.add_argument("share",nargs="+",help="shares to be joined") + parser.set_defaults(func=_reconstruct) + + +def _generate(args): + encoding=getEncoding(args) or "b32" + + shares=generate(args.secret,args.k,args.n,encoding) + for s in shares: + print(s) + + +def _reconstruct(args): + encoding=getEncoding(args) + print(reconstruct(*args.share,encoding=encoding,raw=args.raw)) + + +def getEncoding(args): + if args.hex: return "hex" + elif args.b32: return "b32" + elif args.b64: return "b64" + else: return "" diff --git a/src/shamira.py b/src/shamira.py --- a/src/shamira.py +++ b/src/shamira.py @@ -1,5 +1,4 @@ import os -import sys import re import base64 @@ -61,7 +60,7 @@ def reconstruct(*shares,encoding="",raw= if not encoding: encoding=detectEncoding(shares) - bs=reconstructRaw(decode(s,encoding) for s in shares) + bs=reconstructRaw(*(decode(s,encoding) for s in shares)) return bs if raw else bs.decode(encoding="utf-8") @@ -69,7 +68,8 @@ def encode(share,encoding="b32"): if encoding=="hex": f=base64.b16encode elif encoding=="b32": f=base64.b32encode else: f=base64.b64encode - return ["{0}.{1}".format(i,f(bs).decode("utf8")) for (i,bs) in share] + (i,bs)=share + return "{0}.{1}".format(i,f(bs).decode("utf-8")) def decode(share,encoding="b32"): @@ -79,14 +79,14 @@ def decode(share,encoding="b32"): i=int(i) if encoding=="hex": f=base64.b16decode elif encoding=="b32": f=base64.b32decode - else: f=base64.b32decode + else: f=base64.b64decode shareBytes=f(shareStr) return (i,shareBytes) def detectEncoding(shares): classes=[ - (re.compile(r"\d+\.[0-9a-f]+=*"), "hex"), + (re.compile(r"\d+\.[0-9A-F]+=*"), "hex"), (re.compile(r"\d+\.[A-Z2-7]+=*"), "b32"), (re.compile(r"\d+\.[A-Za-z0-9+/]+=*"), "b64") ] @@ -97,9 +97,5 @@ def detectEncoding(shares): if __name__=="__main__": - secret=sys.argv[1].encode("utf8") - k=int(sys.argv[2]) - n=int(sys.argv[3]) - output=sys.argv[4] if len(sys.argv)>4 else "raw" - for share in generate(secret,k,n,output): - print(share) + import cli + cli.run()