my version of @dis.sociat.ing's dollcode algorithm in python
at main 105 lines 2.8 kB view raw
1import argparse 2import sys 3 4import pyperclip 5 6DOLLCODE_CHARS = ("", "", "") 7BASE_NUM = 3 8 9 10# encodes input string into integer by using ord() & base256 11def encode_base256_int(input: str) -> int: 12 result: int = 0 13 14 for char in input: 15 result = (result * 256) + ord(char) 16 17 return result 18 19 20# decodes input number back in char 21def decode_base256_int(num: int) -> str: 22 output: str = "" 23 24 while num > 0: 25 output = (chr(num % 256)) + output 26 num = num // 256 27 28 return output 29 30 31# converts encoded base256 int -> bijective base-3 numeration 32# then inserts corresponding number (3, 1, 2) into output list 33def encode_dollcode(num: int) -> list[str]: 34 output: list[str] = [] 35 window: int = num 36 mod: int 37 38 while window > 0: 39 mod = window % BASE_NUM 40 41 if mod == 0: 42 window = (window - BASE_NUM) // BASE_NUM 43 else: 44 window = (window - mod) // BASE_NUM 45 46 output.insert(0, DOLLCODE_CHARS[mod]) 47 48 return output 49 50 51# decodes input dollcode -> integer 52def decode_dollcode(input: str) -> int: 53 result: int = 0 54 55 for char in input: 56 if char not in DOLLCODE_CHARS: 57 raise ValueError(f"Invalid character '{char}' in input") 58 elif char == DOLLCODE_CHARS[0]: 59 result = (result + 1) * BASE_NUM 60 else: 61 result = result * BASE_NUM + DOLLCODE_CHARS.index(char) 62 63 return result 64 65 66def main(command: str, input: str, copy: bool): 67 result: str = "" 68 69 try: 70 if command == "decode": 71 result = decode_base256_int(decode_dollcode(input)) 72 else: 73 encoded_dollcode = encode_dollcode(encode_base256_int(input)) 74 result = "".join(encoded_dollcode) 75 76 if copy: 77 pyperclip.copy(result) 78 print(f"{result} -> 📋 copied!") 79 else: 80 print(result) 81 except ValueError as e: 82 print(f"Error: {e}") 83 sys.exit(1) 84 85 86if __name__ == "__main__": 87 parser = argparse.ArgumentParser(description="converts input into dollcode") 88 subparsers = parser.add_subparsers(dest="command", required=True) 89 90 # encode subcommand 91 encode_parser = subparsers.add_parser("encode", help="encode text to dollcode") 92 encode_parser.add_argument("input", type=str, help="text to encode") 93 encode_parser.add_argument( 94 "-c", action="store_true", help="copy output to clipboard" 95 ) 96 97 # decode subcommand 98 decode_parser = subparsers.add_parser("decode", help="decode dollcode to text") 99 decode_parser.add_argument("input", type=str, help="dollcode to decode") 100 decode_parser.add_argument( 101 "-c", action="store_true", help="copy output to clipboard" 102 ) 103 104 args = parser.parse_args() 105 main(args.command, args.input, args.c)