EN
Sign in Publish
contextetech /

Schutzregel DSGVO: Steuer-ID, Telefon und IBAN maskieren

v1
Target model : General (any model) German License: MIT Published on updated 21 hours ago 0 uses

DSGVO-Schutzregel: maskiert Steuer-ID (mit Prüfziffer), Telefonnummern +49, IBAN und private E-Mails in Antworten eines KI-Assistenten. 12 Tests.

Rules

Vor dem Versand alle Daten maskieren, die eine Person identifizieren oder erreichbar machen:
- private E-Mail-Adressen (max.mustermann@…);
- deutsche Telefonnummern, mit oder ohne +49;
- deutsche IBAN;
- Steuer-Identifikationsnummern (Prüfziffer wird geprüft).
Durchlassen: allgemeine Adressen (info@, support@…), Firmennamen, Beträge, Datumsangaben, Bestellnummern.

Test cases

InputExpected
Schreiben Sie an max.mustermann@gmail.com für den Status.Block
Meine Handynummer ist 0151 2345 6789.Block
Rufen Sie mich unter +49 30 1234567 an.Block
Überweisung an DE89 3704 0044 0532 0130 00.Block
Meine Steuer-ID lautet 86095742719.Block
Rechnung bitte an anna.schmidt@firma-gmbh.de.Block
Schreiben Sie an support@contextetech.com bei Fragen.Allow
Ihre Bestellung Nr. 458712 wird morgen versendet.Allow
Der Betrag beträgt 1.250,00 € inkl. MwSt.Allow
Termin am 12.10.2026 um 14 Uhr.Allow
Die Müller Bau GmbH hat das Angebot angenommen.Allow
Hallo, wie kann ich Ihnen helfen?Allow

Code

import re

MUSTER = {
    "email": r"[\w.+-]+@[\w-]+\.[\w.-]+",
    "telefon": r"(?:\+49[\s/-]?|\b0)(?:1[5-7]\d|[2-9]\d{1,3})[\s/-]?\d{3,4}[\s-]?\d{3,5}\b",
    "iban": r"\bDE\d{2}(?:\s?\d{4}){4}\s?\d{2}\b",
    "steuer_id": r"\b[1-9]\d{10}\b",
}
GENERISCH = ("info@", "kontakt@", "support@", "service@", "hallo@")


def steuer_id_gueltig(wert: str) -> bool:
    """Steuerliche Identifikationsnummer: Prüfziffer nach ISO 7064 (MOD 11, 10)."""
    produkt = 10
    for ziffer in wert[:10]:
        summe = (int(ziffer) + produkt) % 10 or 10
        produkt = (summe * 2) % 11
    pruef = 11 - produkt
    return (0 if pruef == 10 else pruef) == int(wert[10])


def maskieren(text: str) -> tuple[str, bool]:
    """Ersetzt personenbezogene Daten durch [<Typ> entfernt]; gibt den Text und True zurück, wenn etwas maskiert wurde."""
    gefunden = False
    for typ, muster in MUSTER.items():
        def ersetzen(m):
            nonlocal gefunden
            wert = m.group(0)
            if typ == "email" and wert.lower().startswith(GENERISCH):
                return wert
            if typ == "steuer_id" and not steuer_id_gueltig(wert):
                return wert
            gefunden = True
            return f"[{typ} entfernt]"
        text = re.sub(muster, ersetzen, text)
    return text, gefunden

Community

No comments yet. Share your feedback, it will help the next person.