Skip to content

Identifier detector

Danish CPR number: format, validation and detection

Updated Denmarknational ID numberDetector key dk_cpr

Short answer

A Danish CPR number is a birth date (DDMMYY) followed by four digits. Maskflare's validator checks that the date is real in the 1900s or 2000s; there is no modulus 11 check.

What it is

The CPR number identifies people in Denmark. Maskflare's Denmark pack covers it as a national ID, and the GDPR (EU/EEA) profile includes the pack.

In Maskflare this is the detector dk_cpr, labelled "Denmark - CPR number (also social security)", category national id number, in the Denmark pack.

Format and layout

  • Ten digits, usually written DDMMYY-XXXX, for example 070761-4285.
  • The first six digits must be a valid day, month and two-digit year.

How the check works

Maskflare checks the date only. The validator applies no modulus 11 rule or any other check digit.

Valid and invalid examples

Synthetic values. Each was run through Maskflare's own validator and pattern when this page was generated.
ExampleResultWhy
070761-4285ValidMatches the layout and passes the validator.
070061-4285InvalidThe invalid example changes one character, character 4 of 11: 7 becomes 0.

In running text the valid example reads, for instance, CPR 070761-4285. The invalid one is left alone: a value that fails the validator is treated as an ordinary string.

Regex and validation caveats

  • With only a date check, any ten digits that begin with a valid date pass. An unhyphenated run is masked unless a word like order or invoice sits closer to it than a CPR keyword (CPR, CPR nr, CPR-nr).
  • The hyphenated form DDMMYY-XXXX is not subject to the bare-run test; only the unhyphenated ten-digit form is.
  • The invalid example changes the month to 00.

Words that confirm it

The formatted shape is masked without a keyword. For a run with no separators, these words count as the detector's own keywords when a word like order, invoice or phone is also close: cpr, cpr nr, cpr-nr, cpr-nummer, id no, id number, identity number, national id, personal id, personal number, personnummer, social insurance, social security, ssn. The nearer word wins.

How to detect it in LLM traffic

Danish CPR number values reach an LLM inside ordinary work rather than as standalone data: a pasted block of HR or payroll rows, a customer-support thread, an onboarding or identity-check form, a spreadsheet someone wants summarised, or an email they want rewritten. The model needs none of the digits for any of those jobs, so the safest place to remove them is before the request leaves the company.

Maskflare reads the whole request body, including the system prompt, earlier messages and tool arguments, so a number buried in the fourth message of a long chat is found as readily as one in the latest message. Each match is replaced with a token such as mf_mask_d7e0 before the request goes out, and with response restoration turned on the real value is put back into the answer for the person who is allowed to see it.

If you build the detection yourself

  1. Strip spaces, dots and hyphens before running any arithmetic, but remember where they were so the original text can be replaced exactly.
  2. Match the shape with a pattern anchored on word boundaries, so that a long digit string is not read as several shorter Danish CPR number candidates.
  3. Apply the layout rules from the section above. This identifier has no check digit to recompute, so expect more look-alikes than with a checksum-based format.
  4. Treat a run with no separators more carefully than a formatted one: reject it when a word such as order, invoice, phone or reference is nearer to it than one of the identifier's own keywords.
  5. Replace the value before the text is sent anywhere, and keep a mapping if the answer has to be restored afterwards.

How Maskflare handles it

  • Protect now, Finance - Protect now, Healthcare and Developer: mask (a reversible token) when Denmark is a primary country.
  • Monitor first: alert (counted, forwarded unchanged) when Denmark is a primary country.

The available actions are mask (reversible token), redact, partial, hash, format-preserving encryption, generalize, alert and block. Masked values are kept encrypted for 30 days so that answers can be restored, then they expire; prompts and responses are not logged. The full list of detectors is in the detector reference.

Compliance profiles that include it

One compliance profile includes the Denmark pack, and applying it turns this detector on: GDPR - EU/EEA. For the GDPR (EU/EEA) profile the Denmark pack is one of the country packs the administrator can choose from; the profile turns on the ones chosen. A profile is a floor: it never turns anything off or weakens a rule that is already stricter.

Frequently asked questions

Does Maskflare apply the modulus 11 test to CPR numbers?

No. The validator checks that the first six digits are a possible date and nothing else.

Why would a ten-digit number not be masked as a CPR?

If it has no hyphen and a word like order, invoice or phone sits closer to it than a CPR keyword, it is treated as something else.

Is the Danish CPR number detector on by default?

It depends on the organisation's primary countries. It is part of the Denmark pack, which the default Protect now template turns on with the action mask when Denmark is a primary country.

Does a valid Danish CPR number prove the person exists?

No. This identifier is validated on its layout alone, so a passing value is only well formed, not known to be real.

Rules on this page describe what Maskflare's detectors and validators check. They are read from the detection catalogue and are not the specification of the body that issues the identifier. Examples are synthetic.

Related pages

See it on your own data

Try Maskflare free.
Bring your hardest prompts.

28-day free trial or 10,000 requests, whichever comes first. Point one app at the gateway or enroll a few laptops,
and watch what gets masked. Or talk to us first.