From 612c65f2ab3b9fa6e1cf1a59a04efd9882f84ade Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Tue, 14 Apr 2020 12:44:09 -0300 Subject: [PATCH] hex-to-base32z.py: add -r flag to do reverse conversion --- contrib/hex-to-base32z.py | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/contrib/hex-to-base32z.py b/contrib/hex-to-base32z.py index 41e561bbc..bf46f4c90 100755 --- a/contrib/hex-to-base32z.py +++ b/contrib/hex-to-base32z.py @@ -3,6 +3,7 @@ import sys base32z_dict = 'ybndrfg8ejkmcpqxot1uwisza345h769' +base32z_map = {base32z_dict[i]: i for i in range(len(base32z_dict))} def lokinet_snode_addr(pk_hex): """Returns the lokinet snode address from a hex ed25519 pubkey""" @@ -21,10 +22,40 @@ def lokinet_snode_addr(pk_hex): result += base32z_dict[val << (5 - bits)] return result + ".snode" -if len(sys.argv) < 2 or any(len(x) != 64 for x in sys.argv[1:]): + +def hex_from_snode(b32z): + """undoes what the above does; b32z should have '.snode' already stripped off""" + assert(len(b32z) == 52) + val = 0 + bits = 0 + for x in b32z: + val = (val << 5) | base32z_map[x] # Arbitrary precision integers FTW + + # `val` is now a 260 bit value (52 * 5 bits per char); but we only use the first bit of the last + # value (which is why lokinet addresses always end with y or o) + assert(b32z[-1] in 'yo') + val >>= 4 + + return "{:64x}".format(val) + + +reverse = False +if len(sys.argv) >= 2 and sys.argv[1] == '-r': + reverse = True + del sys.argv[1] + +if len(sys.argv) < 2 or ( + any(len(x) not in (52, 58) for x in sys.argv[1:]) + if reverse else + any(len(x) != 64 for x in sys.argv[1:]) + ): print("Usage: {} PUBKEY [PUBKEY ...] -- converts ed25519 pubkeys to .snode addresses".format(sys.argv[0])) + print("Usage: {} -r SNODE [SNODE ...] -- converts snode addresses to ed25519 pubkeys".format(sys.argv[0])) sys.exit(1) -for key in sys.argv[1:]: - print("{} -> {}".format(key, lokinet_snode_addr(key))) - +if reverse: + for key in sys.argv[1:]: + print("{}.snode -> {}".format(key[0:52], hex_from_snode(key[0:52]))) +else: + for key in sys.argv[1:]: + print("{} -> {}".format(key, lokinet_snode_addr(key)))