Spaces:
Sleeping
Sleeping
| #!/usr/bin/env python3 | |
| """ | |
| Cifrado de sustituci贸n estilo AES (solo confusi贸n/ofuscaci贸n). | |
| Autor: Denisse Aguilar (ejemplo para maestr铆a en Criptograf铆a) | |
| ------------------------------------------------------------------ | |
| Descripci贸n: | |
| - Genera una S-box (sustituci贸n 1 a 1 de bytes) derivada de una clave. | |
| - Cifra y descifra texto usando solo sustituci贸n (sin difusi贸n). | |
| - Basado en la idea del paso SubBytes del AES. | |
| ------------------------------------------------------------------ | |
| Uso (en terminal o Hugging Face): | |
| from substitution_cipher import encrypt, decrypt | |
| texto_cifrado = encrypt("Hola mundo", "miClave") | |
| decrypt(texto_cifrado, "miClave") | |
| """ | |
| import hashlib | |
| import base64 | |
| import random | |
| # ============================================================== | |
| # 馃攼 Generaci贸n de S-box e inversa | |
| # ============================================================== | |
| def generate_sbox_from_key(key: str): | |
| """ | |
| Genera una tabla de sustituci贸n (S-box) de 256 valores 煤nicos basada en la clave. | |
| """ | |
| # Deriva una semilla num茅rica de la clave usando SHA-256 | |
| key_hash = hashlib.sha256(key.encode("utf-8")).digest() | |
| seed = int.from_bytes(key_hash, "big") | |
| # Usa PRNG determinista (semilla derivada) | |
| rng = random.Random(seed) | |
| sbox = list(range(256)) | |
| rng.shuffle(sbox) # Permutaci贸n aleatoria 0..255 | |
| inv_sbox = [0] * 256 | |
| for i, v in enumerate(sbox): | |
| inv_sbox[v] = i | |
| return sbox, inv_sbox | |
| # ============================================================== | |
| # 馃攣 Funciones de cifrado y descifrado | |
| # ============================================================== | |
| def encrypt(plaintext: str, password: str) -> str: | |
| """ | |
| Cifra un texto (string) usando sustituci贸n de bytes. | |
| Devuelve el resultado en base64. | |
| """ | |
| sbox, _ = generate_sbox_from_key(password) | |
| data = plaintext.encode("utf-8") | |
| encrypted_bytes = bytes([sbox[b] for b in data]) | |
| return base64.b64encode(encrypted_bytes).decode("utf-8") | |
| def decrypt(ciphertext_b64: str, password: str) -> str: | |
| """ | |
| Descifra un texto cifrado en base64 usando la misma clave. | |
| """ | |
| _, inv_sbox = generate_sbox_from_key(password) | |
| encrypted_bytes = base64.b64decode(ciphertext_b64) | |
| decrypted_bytes = bytes([inv_sbox[b] for b in encrypted_bytes]) | |
| return decrypted_bytes.decode("utf-8", errors="ignore") | |
| # ============================================================== | |
| # 馃И Ejemplo de uso | |
| # ============================================================== | |
| if __name__ == "__main__": | |
| import argparse | |
| parser = argparse.ArgumentParser(description="Cifrado por sustituci贸n (solo confusi贸n).") | |
| parser.add_argument("mode", choices=["encrypt", "decrypt"], help="Modo: encrypt o decrypt") | |
| parser.add_argument("text", help="Texto a cifrar o descifrar") | |
| parser.add_argument("--key", required=True, help="Clave secreta") | |
| args = parser.parse_args() | |
| if args.mode == "encrypt": | |
| print(encrypt(args.text, args.key)) | |
| else: | |
| print(decrypt(args.text, args.key)) | |