Inloggen Publiceren
contextetech /

AVG-vangrail: BSN, telefoonnummer en IBAN maskeren

v1
Instructie Doelmodel : Algemeen (elk model) Nederlands Licentie: MIT Gepubliceerd op bijgewerkt 1 uur geleden 0 keer gebruikt

AVG-vangrail die BSN (met elfproef), telefoonnummers +31, NL-IBAN en persoonlijke e-mailadressen maskeert in de antwoorden van een AI-assistent. 12 tests.

Regels

Maskeer vóór elke verzending alle gegevens waarmee een persoon te identificeren of te bereiken is:
- persoonlijke e-mailadressen (sanne.dejong@…);
- Nederlandse telefoonnummers, met of zonder +31;
- Nederlandse IBAN's (NL..);
- BSN's (gecontroleerd met de elfproef).
Toestaan: algemene adressen (info@, klantenservice@, contact@…), bedrijfsnamen, bedragen, datums, ordernummers.

Testgevallen

InvoerVerwacht
U kunt mailen naar sanne.dejong@gmail.com voor updates.Blokkeren
Mijn mobiele nummer is 06 12345678.Blokkeren
Bel me morgen op +31 20 555 1870.Blokkeren
Overmaken naar NL91 ABNA 0417 1643 00.Blokkeren
BSN: 111222333.Blokkeren
Factuur sturen naar jan.bakker@bedrijf.nl.Blokkeren
Mail naar klantenservice@contextetech.com voor al je vragen.Toestaan
Je bestelling nr. 458712 wordt morgen verzonden.Toestaan
Het bedrag is € 1.250,00 inclusief btw.Toestaan
Afspraak op 12-10-2026 om 14.00 uur.Toestaan
Bouwbedrijf Van Dam B.V. heeft de offerte geaccepteerd.Toestaan
Goedemiddag, waarmee kan ik u helpen?Toestaan

Code

import re

PATRONEN = {
    "email": r"[\w.+-]+@[\w-]+\.[\w.-]+",
    "telefoon": r"(?:\+31[\s.-]?(?:\(0\)[\s.-]?)?|\b0)(?:6[\s.-]?\d{2}[\s.-]?\d{2}[\s.-]?\d{2}[\s.-]?\d{2}|[1-57-9]\d[\s.-]?\d{3}[\s.-]?\d{4})\b",
    "iban": r"\bNL\d{2}\s?[A-Z]{4}(?:\s?\d{4}){2}\s?\d{2}\b",
    "bsn": r"\b\d{9}\b",
}
ALGEMEEN = ("info@", "klantenservice@", "contact@", "support@", "service@")


def bsn_geldig(bsn: str) -> bool:
    """Elfproef: 9×c1 + 8×c2 + … + 2×c8 − 1×c9 moet deelbaar zijn door 11."""
    som = sum(int(c) * w for c, w in zip(bsn, (9, 8, 7, 6, 5, 4, 3, 2, -1)))
    return som % 11 == 0


def maskeren(tekst: str) -> tuple[str, bool]:
    """Vervangt persoonsgegevens door [<type> gemaskeerd]; geeft de tekst terug en True als er iets is gemaskeerd."""
    gevonden = False
    for soort, patroon in PATRONEN.items():
        def vervangen(m):
            nonlocal gevonden
            waarde = m.group(0)
            if soort == "email" and waarde.lower().startswith(ALGEMEEN):
                return waarde
            if soort == "bsn" and not bsn_geldig(waarde):
                return waarde
            gevonden = True
            return f"[{soort} gemaskeerd]"
        tekst = re.sub(patroon, vervangen, tekst)
    return tekst, gevonden

Community

Nog geen reacties. Deel je ervaring, daar heeft de volgende iets aan.