The DROP hashing specification, explained
DROP never sends you a name or an email — only SHA-256 hashes. Matching works only if your normalization is byte-identical to the state's. Here are the rules, the composites, and the official test vectors to check your implementation against.
The algorithm
Every identifier is standardized, then hashed with SHA-256 over UTF-8 input, with the digest encoded as standard Base64 including the = padding — not URL-safe Base64. Every hash is exactly 44 characters.
Anna.Smith@Domain.com → normalize → anna.smith@domain.com → SHA-256, UTF-8, Base64 → KA18MT/ph6IHYjzT9zwETySDQyvSh87YuoSBpOQtkhE=
Normalization, identifier by identifier
| Type | Rule | Example |
|---|---|---|
| Remove whitespace, lowercase. Do not strip dots or plus signs. | Anna.Smith@Domain.com → anna.smith@domain.com | |
| Phone | Strip non-numerics; keep the last 10 digits (or all, if fewer). Country codes fall away. | +1(415)555-9317 → 4155559317 |
| DOB | YYYYMMDD, four-digit year. | July 4, 1776 → 17760704 |
| ZIP | Alphanumerics only, drop the +4, lowercase, remove leading zeros, then take the first five characters present. | 00300-9999 → 300 |
| Name | Lowercase; map special Latin (ß→ss, æ→ae); transliterate Greek and Cyrillic; leave CJK/Arabic/Hebrew alone; drop everything that isn't a letter or digit. First and last are hashed separately. | Björn O'Connor-López → bjornoconnorlopez |
| MAID | Hex characters only, lowercase — 32 characters. | a3f1c2d4-5678-… → a3f1c2d4567890ab… |
| VIN / CTV ID | Alphanumerics only, lowercase. | 1HGCM82633A004352 → 1hgcm82633a004352 |
The ZIP rule is the one that bites: leading zeros are stripped before the first-five truncation, so a Puerto Rico ZIP like 00712345 normalizes to 71234, not 00712.
Composite hashes: NDZ and NameVIN
Two of the six list types combine fields. The composite is not a hash of the concatenated values — each field is standardized and hashed on its own, the resulting Base64 strings (padding included) are concatenated with no delimiter, and that string is hashed again.
NDZ = FirstName + LastName + DOB + ZIP (in that order)
danielle → 5dUD1FgiKcTJq+JQ5JZUdlyIXrSbtJ338YYbt5/HNG4=
johnson → K+TjOqPiH2/3rRRPj9WCKKHM47UDQLSAX/DGNIDuxIg=
19850704 → IWi7qxOAbBJe0fNciDj76Eg84gmj40rB7aNMK/VnFOI=
91790 → 2FPZucR4x7U8KlM+SFAX4LPGhwNz/PIZUCSUdDh0o/s=
concat(4 × 44 chars, no separator) → SHA-256 → Base64
↓
NDZ hash = PQOfn1RffEKmqMmNAzDKKaoZCwxWbQZkQzPWmQo9REA=NameVIN works the same way with FirstName + LastName + VIN. Forgetting to include the = padding in the concatenation is the most common way to get a plausible-looking but wrong composite.
Test vectors
The CPPA publishes worked examples. Treat them as a golden test suite — if any of these fail, your matching is wrong and you will under-delete.
email anna.smith@domain.com KA18MT/ph6IHYjzT9zwETySDQyvSh87YuoSBpOQtkhE= phone 4155559317 vGM7y5n+hBXRSEAklhHDPCbysyNgYTmXdMcagGUOY8E= dob 17760704 skXYXxBER6HQTZ3rXSZH1wVGLQ054mS5rbR/bwvzy4I= zip 91790 2FPZucR4x7U8KlM+SFAX4LPGhwNz/PIZUCSUdDh0o/s= zip m1b1a n8L9q8mVeT6Xt9/EeUNiTukGDrkbPJ3DvOEx14uElxk= name juanpablo 91hIbrbzNeqHs3o81O5yNrXUj7wDd2shvZ6THKi9qz8= maid a3f1c2d4567890ab… 250KY6lOgzYUB3EHrkbDCE2kMEZQE69SF38muhoDudI= vin 1hgcm82633a004352 iNswy1m+0VSt8jAfFrvaiQ1R/0HAbgSwNGkwqo6QBss= NDZ (Danielle Johnson…) PQOfn1RffEKmqMmNAzDKKaoZCwxWbQZkQzPWmQo9REA= NameVIN (Eve Genesis + VIN) rtnDuXIe63jXYQQXW5r07GJ7lSsrib8+46QuKFwkOmk=
The sandbox also ships a standardization-and-hashing tool — validate against it before your first real cycle.
Check your own implementation
Our hash checker runs the same engine in your browser — type any identifier and compare.