Skip to content

Text Anonymiser

Replace emails, cards, IBANs, IPs and phone numbers with stable tokens in the browser, and put them back afterwards.

Values replaced
6

6 distinct tokens. The same value always gets the same token, so counts, joins and groupings still work on the masked text.

Email addresses
1
URLs
0
IBANs
1
Card numbers
1
IPv4 addresses
1
Phone numbers
2
Dates
off
Capitalised name candidates
off
Literal terms
0
Estimated tokens after masking
≈ 106
Pseudonymised text
The mapping — this is the key, treat it as the secret
What this assumes: detection is patterns plus checksums, not understanding. Card numbers are Luhn-verified and IBANs mod-97-verified, so lookalikes are left alone; emails, URLs and IPs are shape-matched and are close to exact; phone numbers are a shape with a digit-count filter and will occasionally take a long reference number. Names are the hard case and the capitalised-word detector is off by default because it has genuinely low precision in both directions — it takes headings and misses everyone whose name is one word or is lower-cased. This reduces exposure; it is not a compliance control. Addresses, free-text identifiers, account numbers in prose, dates of birth written out and anything unique enough to re-identify a person in context all survive it. Pseudonymisation is reversible by design, which means the mapping is the secret: with the mapping the text is not anonymous at all, and with enough context neither is the text without it.

Pseudonymisation is not anonymisation, and the difference is the mapping

Replacing every email address with [EMAIL_1] does two useful things at once. It keeps the text usable — the same person is the same token throughout, so a support thread still reads as a conversation and a dataset still groups correctly — and it means the values themselves never reach the provider. That is the pattern the redaction literature calls reversible pseudonymisation, and it is the one that survives a round trip: send the masked text, get the answer back, put the real values back in on your side.

What it is not is anonymisation. A pseudonymised record plus the mapping is the original record, so the mapping inherits every obligation the original had. Keep it out of the prompt, out of your logs, and out of the same store as the masked text. And be honest about the residual: free text re-identifies people through detail rather than identifiers — a role, a date, a location and an unusual complaint together name someone with no email address in sight.

The practical advice is to run this at the point of capture rather than the point of sending. Redaction applied just before the API call leaves the raw text in whatever queue, log line and error report it passed through on the way. Everything here runs in the browser with FileReader, so you can point it at a real support export without that export leaving the machine — which is also the only sensible way to find out what your patterns actually miss.

Text Anonymiser · Multigrid