ES
Iniciar sesión Publicar
contextetech /

Salvaguarda RGPD: ocultar DNI, teléfonos e IBAN

v1
Modelo objetivo : General (cualquier modelo) Español Licencia: MIT Publicado el actualizado hace 20 horas 0 usos

Salvaguarda RGPD que oculta DNI y NIE (letra comprobada), teléfonos +34, IBAN y correos personales en las respuestas de un asistente de IA. 12 pruebas.

Reglas

Ocultar antes del envío cualquier dato que identifique o permita contactar con una persona:
- correos electrónicos personales (ana.garcia@…);
- teléfonos españoles, con o sin +34;
- IBAN españoles;
- DNI y NIE (se comprueba la letra de control).
Dejar pasar: direcciones genéricas (info@, soporte@…), nombres de empresas, importes, fechas, números de pedido.

Casos de prueba

EntradaEsperado
Puede escribir a ana.garcia@gmail.com para el seguimiento.Bloquear
Mi móvil es el 612 345 678.Bloquear
Llámeme al +34 912 345 678 mañana.Bloquear
Transferencia a ES91 2100 0418 4502 0005 1332.Bloquear
Mi DNI es 12345678Z.Bloquear
NIE del cliente: X1234567L.Bloquear
Escriba a soporte@contextetech.com para cualquier duda.Permitir
Su pedido n.º 458712 sale mañana.Permitir
El importe es de 1.250,00 € con IVA.Permitir
La cita es el 12/10/2026 a las 14:00.Permitir
La empresa Construcciones López S.L. aprobó el presupuesto.Permitir
Hola, ¿en qué puedo ayudarle?Permitir

Código

import re

LETRAS = "TRWAGMYFPDXBNJZSQVHLCKE"
PATRONES = {
    "email": r"[\w.+-]+@[\w-]+\.[\w.-]+",
    "telefono": r"(?:\+34[\s.-]?)?\b[6789]\d{2}[\s.-]?\d{3}[\s.-]?\d{3}\b",
    "iban": r"\bES\d{2}(?:\s?\d{4}){5}\b",
    "dni": r"\b[XYZ]?\d{7,8}[\s-]?[A-Z]\b",
}
GENERICOS = ("info@", "contacto@", "soporte@", "hola@", "ventas@")


def dni_valido(valor: str) -> bool:
    """DNI o NIE: la letra final debe coincidir con el número (módulo 23)."""
    v = valor.upper().replace("-", "").replace(" ", "")
    if v[0] in "XYZ":
        v = str("XYZ".index(v[0])) + v[1:]
    return len(v) == 9 and v[:8].isdigit() and LETRAS[int(v[:8]) % 23] == v[8]


def enmascarar(texto: str) -> tuple[str, bool]:
    """Sustituye los datos personales por [<tipo> oculto]; devuelve el texto y True si se ha ocultado algo."""
    encontrado = False
    for tipo, patron in PATRONES.items():
        def sustituir(m):
            nonlocal encontrado
            valor = m.group(0)
            if tipo == "email" and valor.lower().startswith(GENERICOS):
                return valor
            if tipo == "dni" and not dni_valido(valor):
                return valor
            encontrado = True
            return f"[{tipo} oculto]"
        texto = re.sub(patron, sustituir, texto)
    return texto, encontrado

Comunidad

Aún no hay comentarios. Comparte tu opinión, ayudará a los siguientes.