#ip(py): In developt.
This commit is contained in:
parent
0a9172ef04
commit
652867b554
205
Python/AnyankaKeys.py
Normal file
205
Python/AnyankaKeys.py
Normal file
@ -0,0 +1,205 @@
|
||||
#!/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)
|
||||
81
Python/gemini.01.benchmark.py
Normal file
81
Python/gemini.01.benchmark.py
Normal file
@ -0,0 +1,81 @@
|
||||
import timeit
|
||||
import secrets
|
||||
import math
|
||||
|
||||
primes = (0x3FFFFFFB, 0x3FFFFF29, 0x3FFFFF0B, 0x2FFFFFFF, 0x2FFFFF5B)
|
||||
|
||||
# --- Lógica Actual (Bucle) ---
|
||||
def get_multiplier_current(i, multiplier, primes, p_len, jumps, jump):
|
||||
value = (i + multiplier + primes[(i + jump) % p_len]) & 0x3FFFFFFF
|
||||
for _ in range(jumps):
|
||||
shift = 13 + i % 8
|
||||
if i & 1:
|
||||
value ^= (value >> shift)
|
||||
else:
|
||||
value ^= (value << shift)
|
||||
value = (value + primes[i := (i + jump) % p_len]) & 0x3FFFFFFF
|
||||
return value
|
||||
|
||||
# --- Lógica Optimizada (Unrolled) ---
|
||||
def get_multiplier_fast(i, multiplier, primes, p_len, jump):
|
||||
# Asumiendo que jumps siempre es 3
|
||||
value = (i + multiplier + primes[(i + jump) % p_len]) & 0x3FFFFFFF
|
||||
|
||||
# Salto 1
|
||||
shift = 13 + i % 8
|
||||
value ^= (value >> shift if i & 1 else value << shift)
|
||||
value = (value + primes[i := (i + jump) % p_len]) & 0x3FFFFFFF
|
||||
|
||||
# Salto 2
|
||||
shift = 13 + i % 8
|
||||
value ^= (value >> shift if i & 1 else value << shift)
|
||||
value = (value + primes[i := (i + jump) % p_len]) & 0x3FFFFFFF
|
||||
|
||||
# Salto 3
|
||||
shift = 13 + i % 8
|
||||
value ^= (value >> shift if i & 1 else value << shift)
|
||||
value = (value + primes[i := (i + jump) % p_len]) & 0x3FFFFFFF
|
||||
|
||||
return value
|
||||
|
||||
# --- 2. Lógica con While ---
|
||||
def get_multiplier_while(i, multiplier, primes, p_len, jumps, jump):
|
||||
value = (i + multiplier + primes[(i + jump) % p_len]) & 0x3FFFFFFF
|
||||
count = 0
|
||||
while count < jumps:
|
||||
shift = 13 + i % 8
|
||||
if i & 1:
|
||||
value ^= (value >> shift)
|
||||
else:
|
||||
value ^= (value << shift)
|
||||
value = (value + primes[i := (i + jump) % p_len]) & 0x3FFFFFFF
|
||||
count += 1
|
||||
return value
|
||||
|
||||
def get_multiplier_callback(multiplier, primes, p_len, jumps, jump, i = 0):
|
||||
value = ((value ^ (
|
||||
value >> shift if i & 1 else value << shift
|
||||
)) + self.__primes[
|
||||
i := (i + self.__multiplier_jump) % self.__primes_l
|
||||
]) & 0x3FFFFFFF
|
||||
|
||||
# --- Configuración del Test ---
|
||||
primes = (0x3FFFFFFB, 0x3FFFFF29, 0x3FFFFF0B, 0x2FFFFFFF, 0x2FFFFF5B)
|
||||
setup_code = """
|
||||
from __main__ import get_multiplier_current, get_multiplier_fast, primes
|
||||
import secrets
|
||||
"""
|
||||
|
||||
# Ejecución de 1 millón de iteraciones
|
||||
n = 1_000_000
|
||||
|
||||
t_current = timeit.timeit(lambda: get_multiplier_current(5, 1, primes, 5, 3, 7), setup=setup_code, number=n)
|
||||
t_fast = timeit.timeit(lambda: get_multiplier_fast(5, 1, primes, 5, 7), setup=setup_code, number=n)
|
||||
t_secrets = timeit.timeit(lambda: secrets.token_bytes(4), setup=setup_code, number=n)
|
||||
t_while = timeit.timeit(lambda: get_multiplier_while(5, 1, primes, 5, 3, 7), setup=setup_code, number=n)
|
||||
|
||||
print(f"--- Resultados ({n} iteraciones) ---")
|
||||
print(f"Anyanka (Bucle): {t_current:.4f} seg")
|
||||
print(f"Anyanka (Unrolled): {t_fast:.4f} seg")
|
||||
print(f"Secrets (Cripto): {t_secrets:.4f} seg")
|
||||
print(f"Anyanka (While): {t_while:.4f} seg")
|
||||
91
Python/test.py
Normal file
91
Python/test.py
Normal file
@ -0,0 +1,91 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from AnyankaKeys import AnyankaKeys
|
||||
|
||||
class Tests:
|
||||
|
||||
@staticmethod
|
||||
def change_base() -> None:
|
||||
|
||||
for prueba in [
|
||||
[1, 2, 3],
|
||||
[2, 5, 5],
|
||||
[3, 2],
|
||||
[0]
|
||||
]:
|
||||
|
||||
ncripted:list[int] = []
|
||||
decripted:list[int] = []
|
||||
|
||||
def ncript(value:int) -> None:
|
||||
ncripted.insert(0, value)
|
||||
# ncripted.append(value)
|
||||
|
||||
def decript(value:int) -> None:
|
||||
decripted.insert(0, value)
|
||||
# decripted.append(value)
|
||||
|
||||
AnyankaKeys.change_base(prueba, 2, 16, None, ncript)
|
||||
AnyankaKeys.change_base(ncripted, 16, 2, None, decript)
|
||||
|
||||
print(["O", prueba])
|
||||
# print(["A", AnyankaKeys.to_base(prueba, 16, 10, lambda value:print(["C", value]))])
|
||||
# print(["B", list(AnyankaKeys.to_base_old(prueba, 16, 10))])
|
||||
print(["A", ncripted])
|
||||
print(["B", decripted])
|
||||
|
||||
@staticmethod
|
||||
def basic_encript() -> None:
|
||||
|
||||
anyanka:AnyankaKeys = AnyankaKeys({
|
||||
"password": "MiContraseñaSecreta123!@#",
|
||||
})
|
||||
|
||||
for prueba in [
|
||||
"Hola Mundo",
|
||||
"Hola Mundo",
|
||||
"Iola Mundo",
|
||||
"Hola Mundo1",
|
||||
"AnyankaKeys",
|
||||
"1234567890",
|
||||
"!@#$%^&*()_+-=[]{}|;':\",./<>?"
|
||||
]:
|
||||
encrypted:str = anyanka.encrypt(prueba)
|
||||
decrypted:str = anyanka.decrypt(encrypted)
|
||||
|
||||
print(["O", prueba])
|
||||
print(["A", encrypted])
|
||||
print(["B", decrypted])
|
||||
|
||||
@staticmethod
|
||||
def get_hexadecimal() -> None:
|
||||
print(["0x" + hex(value)[2:].upper() for value in (
|
||||
# -- Grupo 1: Constantes de Dispersión Máxima (Golden/Silver Ratios) --
|
||||
2654435761, # 0x9E3779B1 (Knuth's Golden Ratio Prime)
|
||||
1865882353, # Cerca de 2^32 / sqrt(5)
|
||||
3339476533, # Alta entropía
|
||||
|
||||
# -- Grupo 2: Primos "Sucios" (Mezcla perfecta de 0s y 1s) --
|
||||
# Estos números parecen ruido estático en binario.
|
||||
32416190071 & 0xFFFFFFFF, # (Nota: Ajustado a 32 bits si copias de 64) -> Usamos estos directos:
|
||||
2246822519, # Primo cercano a Murmur constant
|
||||
3266489917,
|
||||
668265263,
|
||||
374761393,
|
||||
|
||||
# -- Grupo 3: Primos Grandes (Cercanos al límite de 32-bit signed) --
|
||||
2147483647, # 2^31 - 1 (Mersenne Prime - Clásico)
|
||||
2147483629, # Un poco menos que el máximo
|
||||
2147483587,
|
||||
|
||||
# -- Grupo 4: Primos de "Grano Fino" (Para variedad en rangos medios) --
|
||||
160481183,
|
||||
486187739,
|
||||
999999937, # El primo más grande menor de mil millones
|
||||
1000000007
|
||||
)])
|
||||
|
||||
# Tests.change_base()
|
||||
Tests.basic_encript()
|
||||
# Tests.get_hexadecimal()
|
||||
Loading…
Reference in New Issue
Block a user