| Suppression / redaction | Drop the column or null the cell | direct identifiers with no analytic value; high-risk QI you can afford to lose | No | Suppressing only the visible identifier while a perfect-correlate column survives (e.g. drop name, keep full_address) — re-id intact |
| Masking (static) | Replace part with a constant (***-**-1234) | display / partial-match needs; low downstream value | No (lossy) | Naïve masking of a quasi-identifier is not de-identification — masked ZIP-3 + DOB still links. Masking ≠ anonymization |
| Tokenization (reversible vault) | Map value → random token; original held in a separate vault | you must re-join later (ops, fraud, longitudinal linkage) | Yes (with vault) | The vault is a new high-value attack surface + a re-identification key. If the vault leaks or is in-scope for the same access role, you've added risk, not removed it. Token must carry zero residual signal (no format leakage, no sequential IDs) |
| Pseudonymization (keyed) | Deterministic keyed replacement; same input → same pseudonym | preserve referential integrity across tables without a lookup vault | Yes (with key) | GDPR-pseudonymous data is still personal data — re-identifiable by the key holder. Deterministic mapping is vulnerable to dictionary/frequency attack on low-cardinality fields |
| Hashing (salted) | One-way digest, per-record or global salt | irreversible matching / dedup join key | No (one-way) | Unsalted/low-entropy hashes are trivially reversed by rainbow table (email, phone — finite space). Global salt → cross-record linkage survives; per-record salt → breaks the join you wanted. Hashing a QI does not add anonymity — same value still collides |
| Generalization / binning | Coarsen to a range (age→band, ZIP5→ZIP3, timestamp→month) | the primary QI lever to reach a k-anonymity target | No (lossy) | Over-generalization destroys the signal the model needs (age→"adult"); under-generalization misses k. Outliers (age 109) stay unique even after binning — needs top/bottom-coding |
| k-anonymity | Generalize/suppress until every QI combo appears ≥ k times | structured release where QI linkage is the threat | No | k-anonymity alone leaks the sensitive attribute via homogeneity (all k rows share one diagnosis) and background-knowledge attacks. k is necessary, not sufficient |
| l-diversity | Each QI class has ≥ l distinct sensitive values | k-anonymity holds but sensitive attribute is skewed | No | Doesn't defend skewness/similarity attacks (l "diverse" values all in the same sensitive range). Expensive in utility on rare sensitive values |
| t-closeness | Sensitive distribution per QI class is within t of the global distribution | l-diversity insufficient (semantic closeness of values) | No | Strongest of the three but most utility-destructive; hard to satisfy on naturally clustered attributes. Often forces heavy suppression |
| Differential privacy (on aggregates) | Calibrated noise so any one record's presence is bounded (ε) | you release statistics / counts / model gradients, not row-level data | No (row-level not released) | Wrong tool for releasing a usable row-level dataset. Small ε destroys utility; large ε is privacy theatre. Budget composes across queries — track cumulative ε or it silently exhausts |
| Format-preserving encryption (FPE) | Encrypt while keeping type/length (16-digit→16-digit) | downstream systems require valid-looking formats (test data, legacy schemas) | Yes (with key) | Reversible — key custody is the whole security story. Preserves cardinality and uniqueness, so it does nothing for QI-linkage risk; it protects the value, not the identifiability |