Coverage for presidio_analyzer / predefined_recognizers / country_specific / germany / de_fuehrerschein_recognizer.py: 100%
9 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-03-29 09:03 +0000
« prev ^ index » next coverage.py v7.13.1, created at 2026-03-29 09:03 +0000
1from typing import List, Optional
3from presidio_analyzer import Pattern, PatternRecognizer
6class DeFuehrerscheinRecognizer(PatternRecognizer):
7 r"""
8 Recognizes German Führerscheinnummern (driving license numbers).
10 The Führerscheinnummer is the document number printed in Field 5 of the
11 German driving license card. Since the EU-harmonized credit-card format
12 was introduced on 19 January 2013 (EU Directive 2006/126/EC, implemented
13 via FeV reform), the number follows a fixed 11-character structure:
15 Pos 1–2: Behördenkürzel – 2 uppercase letters identifying the issuing
16 Fahrerlaubnisbehörde (derived from the Kfz-Zulassungskürzel of
17 the issuing Kreis/Stadt, e.g. "B0" Berlin, "MU" München,
18 "HH" Hamburg, "KO" Koblenz)
19 Pos 3–5: Behördennummer – 3-digit authority code within the Bundesland
20 (assigned by the Kraftfahrt-Bundesamt, KBA)
21 Pos 6–10: Laufende Nummer – 5-digit sequential issue number
22 Pos 11: Prüfzeichen – 1 check character (uppercase letter A–Z or
23 digit 0–9); the derivation algorithm is not published by KBA
25 Legal basis: FeV Anlage 8 (Fahrerlaubnis-Verordnung, Anlage 8 – Muster des
26 Führerscheins), KBA Schlüsselverzeichnis der Fahrerlaubnisbehörden.
27 EU standard: Annex I to Directive 2006/126/EC (Field 5).
28 Data protection: DSGVO Art. 4 Nr. 1 (personenbezogene Daten), BDSG.
30 Examples (fictitious): B012345678A, MU12345678B, HH98765432C
32 Scope note: Pre-2013 German driving licenses (pink folded card, laminated
33 card) used locally defined, non-standardized number formats and remain
34 legally valid until 2033 under EU grandfathering rules. Their numbers do
35 not reliably fit the 11-character pattern and are therefore out of scope
36 for this recognizer. Context words (e.g. "Führerschein", "Fahrerlaubnis")
37 remain the primary means of distinguishing true license numbers from
38 other 11-character alphanumeric codes.
40 No checksum validation is implemented because the Prüfzeichen derivation
41 formula is not published in FeV Anlage 8 or KBA administrative documents.
43 Accuracy note: The pattern ``[A-Z]{2}\\d{8}[A-Z0-9]`` (11 characters) is
44 fairly specific, but context words are required for high-confidence matches
45 because no computable checksum is available. The base confidence is set to
46 0.35. Formal accuracy evaluation has not been performed on a labelled dataset.
48 :param patterns: List of patterns to be used by this recognizer
49 :param context: List of context words to increase confidence in detection
50 :param supported_language: Language this recognizer supports
51 :param supported_entity: The entity this recognizer can detect
52 """
54 PATTERNS = [
55 Pattern(
56 "Führerscheinnummer (Post-2013 EU-Format, 11 Zeichen)",
57 r"\b[A-Z]{2}\d{8}[A-Z0-9]\b",
58 0.35,
59 ),
60 ]
62 CONTEXT = [
63 "führerscheinnummer",
64 "führerschein",
65 "fahrerlaubnis",
66 "fahrerlaubnisnummer",
67 "fahrerlaubnisklasse",
68 "führerscheininhaber",
69 "fev",
70 "kba",
71 "kraftfahrt-bundesamt",
72 "driving licence",
73 "driving license",
74 "driver's license",
75 "licence number",
76 "license number",
77 "dokument nr",
78 "dokument-nr",
79 "feld 5",
80 ]
82 def __init__(
83 self,
84 patterns: Optional[List[Pattern]] = None,
85 context: Optional[List[str]] = None,
86 supported_language: str = "de",
87 supported_entity: str = "DE_FUEHRERSCHEIN",
88 name: Optional[str] = None,
89 ):
90 patterns = patterns if patterns else self.PATTERNS
91 context = context if context else self.CONTEXT
92 super().__init__(
93 supported_entity=supported_entity,
94 patterns=patterns,
95 context=context,
96 supported_language=supported_language,
97 name=name,
98 )