diff options
-rwxr-xr-x | Com/Simatime/roun | 227 |
1 files changed, 0 insertions, 227 deletions
diff --git a/Com/Simatime/roun b/Com/Simatime/roun deleted file mode 100755 index addbaf3..0000000 --- a/Com/Simatime/roun +++ /dev/null @@ -1,227 +0,0 @@ -#!/usr/bin/env python3 - -import argparse - -DESC = """roun is a program that takes numbers and turns them into human-readable -names, and vice versa. - -A 'roun' is the human-readable name. For example: - - roun = hidor-kahih - ip = 68.107.97.20 - hex = 0x446b6114 - int = 1147887892 - -The names are inspired by proquints <https://arxiv.org/html/0901.4016>. - -Currently the algorithm is the same, but I would like to modify the algorithm at -some point to be less odd than what proquints currently is. When I get time. -""" - - -def _char_list_to_dict(char_list): - return {c: k for (c, k) in zip(char_list, range(len(char_list)))} - - -UINT_TO_CONSONANT = "bdfghjklmnprstvz" -UINT_TO_VOWEL = "aiou" - -CONSONANT_TO_UINT = _char_list_to_dict(UINT_TO_CONSONANT) -VOWEL_TO_UINT = _char_list_to_dict(UINT_TO_VOWEL) - -MASK_LAST4 = 0xF -MASK_LAST2 = 0x3 - -CHARS_PER_CHUNK = 5 - - -def _uint16_to_roun(uint16_val): - val = uint16_val - res = ["?"] * CHARS_PER_CHUNK - for i in range(CHARS_PER_CHUNK): - if i & 1: - res[-i - 1] = UINT_TO_VOWEL[val & MASK_LAST2] - val >>= 2 - else: - res[-i - 1] = UINT_TO_CONSONANT[val & MASK_LAST4] - val >>= 4 - return "".join(res) - - -def uint_to_roun(uint_val, separator="-"): - """Convert 32-bit integer value into corresponding roun string identifier. - - >>> uint_to_roun(0x7F000001, '-') - lusab-babad - - :param uint_val: 32-bit integer value to encode - :param separator: string to separate character rounets - :return: roun string identifier - """ - if uint_val < 0 or uint_val > 0xFFFFFFFF: - raise ValueError("uint_val should be in range 0-0xFFFFFFFF") - return _uint16_to_roun(uint_val >> 16) + separator + _uint16_to_roun(uint_val) - - -def roun_to_uint(roun): - """Convert roun string identifier into corresponding 32-bit integer value. - - >>> hex(roun_to_uint('lusab-babad')) - '0x7F000001' - - :param roun: roun string identifier to decode - :return: 32-bit integer representation of the roun encoded value - """ - nchar = len(roun) - if nchar < 10 or nchar > 11: - raise ValueError("roun should be in form of two rounets + optional separator") - - res = 0 - for i, c in enumerate(roun): - mag = CONSONANT_TO_UINT.get(c) - if mag is not None: - res <<= 4 - res += mag - else: - mag = VOWEL_TO_UINT.get(c) - if mag is not None: - res <<= 2 - res += mag - elif i != 5: - raise ValueError("bad roun format") - return res - - -def ip2uint_str(ipv4_str): - """Convert IPv4 string to 32-bit integer value""" - parts = ipv4_str.split(".") - if len(parts) != 4: - raise ValueError( - "Expected IPv4 address in form A.B.C.D, got {}".format(ipv4_str) - ) - ip = [0] * 4 - for i, part in enumerate(parts): - try: - int_part = int(part) - except ValueError: - raise ValueError("Part {} of IPv4 address is not an integer".format(i)) - if int_part < 0 or int_part > 255: - raise ValueError("Part {} of IPv4 address is not in range 0-255".format(i)) - ip[i] = int_part - return (ip[0] << 24) + (ip[1] << 16) + (ip[2] << 8) + ip[3] - - -def uint_to_ip_str(uint_val): - "Covert 32-bit integer value to IPv4 string" - return "{}.{}.{}.{}".format( - (uint_val >> 24) & 0xFF, - (uint_val >> 16) & 0xFF, - (uint_val >> 8) & 0xFF, - uint_val & 0xFF, - ) - - -def uint_to_roun_str(uint_str, separator="-"): - return uint_to_roun(int(uint_str), separator) - - -def roun_to_uint_str(roun): - return str(roun_to_uint(roun)) - - -def hex2roun_str(hex_str, separator="-"): - return uint_to_roun(int(hex_str, 16), separator) - - -def roun2hex_str(roun): - return hex(roun_to_uint(roun)) - - -def convert(str_val, target=None): - """Convert between roun, integer, hex or IPv4 string representations. - Tries to guess the representation from input. - :param str_val: input representation (string) - :return: output representation (string) - """ - if target is not None and target not in {"uint", "hex", "ip"}: - raise ValueError("Convert target should be one of: uint, hex, ip") - - if target == "uint": - return roun_to_uint_str(str_val) - - if target == "hex": - return roun2hex_str(str_val) - - if target == "ip": - return uint_to_ip_str(roun_to_uint(str_val)) - - # try to guess the representation - try: - return roun_to_uint_str(str_val) - except ValueError: - pass - - try: - return uint_to_roun_str(str_val) - except ValueError: - pass - - try: - return hex2roun_str(str_val) - except ValueError: - pass - - try: - return uint_to_roun_str(ip2uint_str(str_val)) - except ValueError: - pass - - raise ValueError("Unrecognized input format: {}".format(str_val)) - - -if __name__ == "__main__": - parser = argparse.ArgumentParser( - description=DESC, formatter_class=argparse.RawDescriptionHelpFormatter - ) - parser.add_argument( - "-n", - "--uint", - action="store_true", - help="convert from roun to 32-bit integer", - required=False, - ) - parser.add_argument( - "-x", - "--hex", - action="store_true", - help="convert from roun to hexadecimal", - required=False, - ) - parser.add_argument( - "-i", - "--ip", - action="store_true", - help="convert from roun to IPv4", - required=False, - ) - parser.add_argument( - "val", - nargs="?", - type=str, - default=None, - help="value to convert (if not specified, " - "IP address of the current host is printed)", - ) - - args = parser.parse_args() - - target = None - if args.uint: - target = "uint" - elif args.hex: - target = "hex" - elif args.ip: - target = "ip" - - res = convert(args.val, target) - print("{}".format(res)) |