#!/usr/bin/env python # -*- coding: utf-8 -*- from typing import Any, Self, Callable, Optional, TypeVar, Iterable from time import time from re import compile as re_compile, Pattern as RePattern, I as RE_IgnoreCase T = TypeVar("T", int, float, str, bytes) class AnyankaKeys: __slots__:tuple[str] = ( '__alphabet', '__dictionary', '__private_key', '__private_key_l', '__multiplier', '__primes', '__primes_l', '__multiplier_jumps', '__multiplier_jump', '__base', '__encrypt_i', '__password', '__password_l' ) ALPHABET:tuple[str] = tuple("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz") PRIVATE_KEY:tuple[int] = tuple(range(1, 0x100)) MULTIPLIER:int = 1 MULTIPLIER_JUMPS:int = 3 MULTIPLIER_JUMP:int = 7 PRIMES:tuple[int] = ( 0x3FFFFFFB, 0x3FFFFF29, 0x3FFFFF0B, 0x2FFFFFFF, 0x2FFFFF5B, 0x1FFFFFFF, 0x279DB13D, 0x279DB113, 0x2AAAAAAB, 0x1555556B, 0x27D4EB2F, 0x165667B1, 0x1000007F, 0x3B9ACA07, 0x01000193, 0x1EADBEEF, 0x0AFEBABE, 0x0BADC0DE, 0x3B9AC9C1, 0x1D295C4D, 0x990BF9F, 0x1CFAA2DB, 0xDEADBEEF, 0xCAFEBABF, 0xBAADF00D ) RE_KEY:RePattern = re_compile(r'^[a-z_][a-z0-9_]*$', RE_IgnoreCase) def __init__(self:Self, inputs:Optional[dict[str, Any|None]] = None) -> None: self.__alphabet:tuple[str] = tuple(self.unique(self.get_value("alphabet", inputs, self.ALPHABET))) self.__dictionary:dict[str, int] = {value : index for index, value in enumerate(self.__alphabet)} self.__private_key:tuple[int] = tuple(self.get_value("private_key", inputs, self.PRIVATE_KEY)) self.__private_key_l:int = len(self.__private_key) self.__multiplier:int = self.get_value("multiplier", inputs, self.MULTIPLIER) self.__primes:tuple[int] = tuple(self.get_value("primes", inputs, self.PRIMES)) self.__primes_l:int = len(self.__primes) self.__multiplier_jumps:int = self.get_value("multiplier_jumps", inputs, self.MULTIPLIER_JUMPS) self.__multiplier_jump:int = self.get_value("multiplier_jump", inputs, self.MULTIPLIER_JUMP) l:int = len(self.__alphabet) self.__base:int = self.get_value("base", inputs, l) self.__encrypt_i:int = 0 self.__password:tuple[int] = (0,) self.__password_l:int = 1 self.set_password(self.get_value("password", inputs, "")) if self.__base > l: self.__base = l def set_password(self:Self, password:str) -> None: if password: password_changed:list[int] = [] self.change_base(password, self.__base, input_handler = ord, output_handler = password_changed.append) self.__password = tuple(password_changed) else: self.__password = (0,) self.__password_l = len(self.__password) def __get_multiplier(self:Self, i:int) -> int: value:int = (i + self.__multiplier + self.__primes[ i := (i + self.__multiplier_jump) % self.__primes_l ]) & 0x3FFFFFFF for _ in range(self.__multiplier_jumps): shift:int = 13 + i % 8 value = ((value ^ ( value >> shift if i & 1 else value << shift )) + self.__primes[ i := (i + self.__multiplier_jump) % self.__primes_l ]) & 0x3FFFFFFF return value def encrypt(self:Self, data:str) -> str: i:int = self.__get_multiplier(self.__encrypt_i + len(data) + int(time() % 1 * 1000)) % self.__base summatory:str = self.__alphabet[i] encrypted:list[str] = [] self.__encrypt_i += i i -= 1 def output_handler(value:int) -> None: nonlocal encrypted, i multiplier:int = self.__get_multiplier(i := i + 1) encrypted.append(self.__alphabet[(multiplier + value + self.__private_key[ multiplier // self.__base % self.__private_key_l ] + self.__password[multiplier % self.__password_l]) % self.__base]) self.change_base(data, self.__base, 0x100, input_handler = ord, output_handler = output_handler ) return summatory + "".join(reversed(encrypted)) def decrypt(self:Self, data:str) -> str: i:int = len(data[1:]) + self.__dictionary[data[0]] decrypted:list[str] = [] def output_handler(value:int) -> None: nonlocal decrypted decrypted.append(chr(value)) def input_handler(value:str) -> int: nonlocal i multiplier:int = self.__get_multiplier(i := i - 1) return (self.__dictionary[value] - self.__private_key[ multiplier // self.__base % self.__private_key_l ] - multiplier - self.__password[multiplier % self.__password_l]) % self.__base self.change_base(data[1:], 0x100, self.__base, input_handler = input_handler, output_handler = output_handler ) return "".join(reversed(decrypted)) @classmethod def get_keys(cls:type[Self], *inputs:Iterable[Any|None]) -> list[str]: keys:list[str] = [] for item in inputs: if isinstance(item, str): cls.RE_KEY.match(item) and item in keys or keys.append(item) elif isinstance(item, (list, tuple)): keys.extend(cls.get_keys(*item)) return keys @classmethod def get_dictionaries(cls:type[Self], *inputs:Iterable[Any|None]) -> list[dict[str, Any|None]]: dictionaries:list[dict[str, Any|None]] = [] for item in inputs: if isinstance(item, dict): dictionaries.append(item) elif isinstance(item, (list, tuple)): dictionaries.extend(cls.get_dictionaries(*item)) return dictionaries @classmethod def get_value( cls:type[Self], keys:str|list[str]|tuple[str, ...], inputs:dict[str, Any|None]|Iterable[Any|None], default:Optional[Any] = None ) -> Any|None: if len(keys := cls.get_keys(keys)): for dictionary in cls.get_dictionaries(inputs): for key in keys: if key in dictionary: return dictionary[key] return default @staticmethod def unique(items:Iterable[Any|None]) -> list[Any|None]: return list(dict.fromkeys(items)) @staticmethod def change_base( data:Iterable[T], to_base:int, from_base:int = 0x100, input_handler:Optional[Callable[[T], int]] = None, output_handler:Optional[Callable[[int], None]] = None ) -> None: stack:int = 0 value:int has:bool = False if input_handler is None:input_handler = lambda value:value if output_handler is None:output_handler = lambda value:value for value in data: stack = stack * from_base + input_handler(value) while stack >= to_base: has = True stack, value = divmod(stack, to_base) output_handler(value) (not has or stack) and output_handler(stack)