Skip to main content

Hashing Algorithm

This article specifies the standardization and hashing rules required by California's DROP system. If you choose the pre-hashed ingestion path, you must implement these rules exactly. If you use the clear ingestion path, DataGrail handles this for you — but this reference is useful for understanding how matching works.

Legal Basis

The hashing rules are defined by:

  • California Delete Act (Civil Code section 1798.99.80 et seq.)
  • CCR, title 11, section 7600 et seq.
  • CalPrivacy DROP Technical Documentation (updated 2026)

General Process

For every identifier field:

  1. Standardize the value using the field-specific rules below
  2. Encode the standardized value as UTF-8
  3. Hash with SHA-256
  4. Encode the hash output as Base64

A DROP hash is always a 44-character Base64 string (typically ending with =).

Input → Standardize → UTF-8 bytes → SHA-256 → Base64 → 44-char string

Field Standardization Rules

Email

The following rules apply to email addresses before hashing:

RuleExample
Trim leading/trailing whitespace" alice@co.com ""alice@co.com"
Lowercase the entire address"Alice@Co.COM""alice@co.com"
Do not remove dots, plus signs, or other characters"a.lice+tag@co.com" stays as-is

Phone

The following rules apply to phone numbers before hashing:

RuleExample
Strip all non-numeric characters"+1(415)555-9317""14155559317"
Keep the last 10 digits (or all digits if fewer than 10)"14155559317""4155559317"

Test vectors:

InputStandardizedSHA-256 Base64
+1(415)555-93174155559317vGM7y5n+hBXRSEAklhHDPCbysyNgYTmXdMcagGUOY8E=
+84(90)123 45674901234567ptzVkgbv9DonwvPCHmXmJ2SEOaolSh37z3ZzY/Gmm+U=

Name (First Name, Last Name — hashed separately)

The following rules apply to first and last names before hashing:

RuleExample
Replace accented Latin characters with ASCII"José""jose"
Transliterate Greek and Cyrillic to Latin"Иван""ivan"
Do not transliterate CJK, Arabic, or HebrewCharacters kept as-is
Compound first names → single unit (remove spaces)"Juan Pablo""juanpablo"
Remove hyphens, apostrophes, spaces"O'Brien""obrien"
Lowercase"SMITH""smith"

Test vectors:

InputStandardizedSHA-256 Base64
Juan Pablojuanpablo91hIbrbzNeqHs3o81O5yNrXUj7wDd2shvZ6THKi9qz8=
Martinezmartinez2wRPGbwBNxhShjRczx8GfS2c4cjvs4NJskeWloUNtp8=

Date of Birth

The following rule applies to dates of birth before hashing:

RuleExample
Format as YYYYMMDD"July 4, 1776""17760704"

Test vector:

InputStandardizedSHA-256 Base64
July 4, 177617760704skXYXxBER6HQTZ3rXSZH1wVGLQ054mS5rbR/bwvzy4I=

ZIP / Postal Code

The following rules apply to ZIP and postal codes before hashing. Note that all four rules must be applied in order — the "Lowercase" example below shows an intermediate value before truncation.

RuleExample
Keep alphanumeric characters only"91790-3771""917903771"
Lowercase"M1B 1A1""m1b1a1"
Take first 5 characters"917903771""91790" / "m1b1a1""m1b1a"
Remove leading zeros"01234""1234"

Test vectors:

InputStandardizedSHA-256 Base64
91790-3771917902FPZucR4x7U8KlM+SFAX4LPGhwNz/PIZUCSUdDh0o/s=
M1B 1A1m1b1an8L9q8mVeT6Xt9/EeUNiTukGDrkbPJ3DvOEx14uElxk=

VIN (Vehicle Identification Number)

The following rules apply to VINs before hashing:

RuleExample
Keep alphanumeric characters onlyAlready alphanumeric
Lowercase"1HGCM82633A004352""1hgcm82633a004352"
Must be exactly 17 characters after normalization

MAID (Mobile Advertising ID)

The following rules apply to MAIDs before hashing:

RuleExample
Keep hex characters only (0-9, a-f)Strip hyphens from GUID format
Lowercase"A1B2C3D4...""a1b2c3d4..."
Must be exactly 32 characters after normalization

CTVID (Connected TV ID)

The following rules apply to CTVIDs before hashing:

RuleExample
Keep alphanumeric characters only
Lowercase
Must be 8–32 characters after normalization

Composite Hashing

DROP defines two composite list types that hash multiple fields together. The process is:

  1. Standardize and hash each component field separately (producing a Base64 string per field)
  2. Concatenate the Base64 strings in the specified order with no separator
  3. Encode the concatenated string as UTF-8
  4. Hash the concatenation with SHA-256
  5. Encode as Base64
field_1_hash = Base64(SHA256(standardize(field_1)))
field_2_hash = Base64(SHA256(standardize(field_2)))
composite = Base64(SHA256(field_1_hash + field_2_hash + ...))

NDZ: First Name + Last Name + DOB + ZIP

Concatenation order: hash(first) + hash(last) + hash(dob) + hash(zip)

Worked example: Danielle Johnson, born July 4, 1985, ZIP 91790

FieldStandardizedSHA-256 Base64
First Namedanielle5dUD1FgiKcTJq+JQ5JZUdlyIXrSbtJ338YYbt5/HNG4=
Last NamejohnsonK+TjOqPiH2/3rRRPj9WCKKHM47UDQLSAX/DGNIDuxIg=
DOB19850704IWi7qxOAbBJe0fNciDj76Eg84gmj40rB7aNMK/VnFOI=
ZIP917902FPZucR4x7U8KlM+SFAX4LPGhwNz/PIZUCSUdDh0o/s=

Final NDZ hash: PQOfn1RffEKmqMmNAzDKKaoZCwxWbQZkQzPWmQo9REA=

NameVIN: First Name + Last Name + VIN

Concatenation order: hash(first) + hash(last) + hash(vin)

Worked example: Eve Genesis, VIN 1HGCM82633A004352

FieldStandardizedSHA-256 Base64
First NameevehSYq33RRi7twx8uUzWFZ2RZp5age3x7+vVQ+rb2p+is=
Last NamegenesisruutSnlvzC4V3ExgYbRe2bNz8mrfx5jKfS2MxYGCcY4=
VIN1hgcm82633a004352iNswy1m+0VSt8jAfFrvaiQ1R/0HAbgSwNGkwqo6QBss=

Final NameVIN hash: rtnDuXIe63jXYQQXW5r07GJ7lSsrib8+46QuKFwkOmk=

Multiple VINs

If a consumer has multiple VINs, generate one NameVIN hash per VIN (same name fields, different VIN each time).


DROP List Types Summary

The table below maps each DROP list type to its hash input and required fields:

List TypeHash InputRequired Fields
EmailSingle email addressemails[]
PhoneSingle phone numberphones[]
NDZFirst + Last + DOB + ZIP (composite)name.first, name.last, dob, zip
NameVINFirst + Last + VIN (composite)name.first, name.last, vins[]
MAIDSingle Mobile Ad IDmaids[]
CTVIDSingle Connected TV IDctvids[]

Implementation Checklist

Before submitting your first ingestion, verify each of the following:

  1. Implement each field standardization rule exactly as specified
  2. Verify SHA-256 output using the test vectors above
  3. Verify Base64 encoding (standard Base64 with = padding, not URL-safe)
  4. For composites (NDZ, NameVIN): hash fields individually first, then concatenate the Base64 strings, then hash the concatenation
  5. For consumers with multiple values (e.g., 3 emails), produce one hash per value
  6. For consumers with multiple VINs, produce one NameVIN hash per VIN
  7. Validate your output against the reference implementation before submitting your first ingestion

 

Need help?
If you have any questions, please reach out to your dedicated Account Manager or contact us at support@datagrail.io.

Disclaimer: The information contained in this message does not constitute as legal advice. We would advise seeking professional counsel before acting on or interpreting any material.