Ferramentas/RCVinculaPartesLivroAntigo/actions/hexCipher/hex_chipher.py
2025-12-02 10:37:13 -03:00

124 lines
4.4 KiB
Python

class HexCipher:
"""
Um cifrador simples e reversível baseado em:
- XOR com chave
- Inversão de texto
- Representação em hexadecimal
Inspirado no componente original Delphi TEvCriptografa.
"""
# -------------------------------------------------------------------------
# Construtor
# -------------------------------------------------------------------------
def __init__(self, key: str = "123", ignore_fields: list[str] | None = None):
"""Inicializa a classe com a chave fornecida."""
self._key = key
# nomes de campos que NÃO devem ser descriptografados (sempre minúsculos)
self._ignore_fields = (
{f.lower() for f in ignore_fields} if ignore_fields else set()
)
# -------------------------------------------------------------------------
# Métodos públicos principais
# -------------------------------------------------------------------------
def encrypt(self, text: str) -> str:
"""
Recebe um texto puro e retorna sua versão criptografada em hexadecimal.
"""
binary_cipher = self._text_to_binary_cipher(text)
hex_cipher = "".join(self._decimal_to_hex(ord(c)) for c in binary_cipher)
return hex_cipher
def decrypt(self, hex_string: str) -> str:
"""
Recebe um texto criptografado em hexadecimal e retorna o texto puro.
"""
chars = []
for i in range(0, len(hex_string), 2):
hex_pair = hex_string[i : i + 2]
chars.append(chr(self._hex_to_decimal(hex_pair)))
binary_str = "".join(chars)
return self._binary_to_text(binary_str)
def decrypt_safe(self, value: str, field: str | None = None) -> str:
"""
Descriptografa com segurança:
- Se o campo estiver em _ignore_fields, retorna o valor original.
- Se o valor não parecer HEX válido, retorna o valor original.
- Em qualquer erro na descriptografia, retorna o valor original.
"""
# 1) Campo explicitamente ignorado
if field and field.lower() in self._ignore_fields:
return value
# 2) Valor vazio / None
if not value:
return value
# 3) Verifica se é HEX puro (somente 0-9 A-F) e tamanho par
import re
if re.fullmatch(r"[0-9A-Fa-f]+", value) is None:
return value
if len(value) % 2 != 0:
return value
# 4) Tenta descriptografar
try:
return self.decrypt(value)
except Exception:
return value
# -------------------------------------------------------------------------
# Funções internas de criptografia/descriptografia
# -------------------------------------------------------------------------
def _text_to_binary_cipher(self, text: str) -> str:
"""
Criptografa um texto aplicando:
1. Inversão de caracteres.
2. Operação XOR entre cada caractere e um valor derivado da chave.
"""
text = self._reverse(text)
result = []
for position, char in enumerate(text, start=1):
key_char = self._key[position % len(self._key)]
key_value = ord(key_char) + position
result.append(chr(ord(char) ^ key_value))
return "".join(result)
def _binary_to_text(self, cipher_text: str) -> str:
"""
Descriptografa um texto binário cifrado por XOR.
O processo é simétrico: aplica o mesmo XOR e inverte novamente.
"""
result = []
for position, char in enumerate(cipher_text, start=1):
key_char = self._key[position % len(self._key)]
key_value = ord(key_char) + position
result.append(chr(ord(char) ^ key_value))
return self._reverse("".join(result))
# -------------------------------------------------------------------------
# Funções auxiliares
# -------------------------------------------------------------------------
def _reverse(self, text: str) -> str:
"""Inverte a ordem dos caracteres de uma string."""
return text[::-1]
def _decimal_to_hex(self, number: int) -> str:
"""Converte um número decimal (byte) em uma string hexadecimal de 2 dígitos."""
return f"{number:02X}"
def _hex_to_decimal(self, hex_str: str) -> int:
"""Converte uma string hexadecimal de 2 dígitos em seu valor decimal (byte)."""
return int(hex_str, 16)