Skip to content

Identity and hashing

Moonbrush research note 5

Version
1.0
Published
October 20, 2026
Checked against the product
October 19, 2026
Authors
Moonbrush

Keywordsrecord linkage; entity resolution; deterministic matching; pseudonymization; SHA-256; re-identification; k-anonymity; Global Privacy Control

Abstract

Every count Moonbrush reports depends on deciding which person a record belongs to, and campaign packages carry identifiers as SHA-256 hashes. This note sets out the research behind both.

The record-linkage literature describes two kinds of error, joining records of different people and failing to join records of the same person, and a theory for trading one against the other. Moonbrush resolves deterministically and leaves ambiguous matches unattached, which trades more missed links for fewer false links: for counting results, the safer error, because a false link can manufacture a result. For suppression its rule falls the other way: an ambiguous opt-out suppresses every candidate. On hashing, the security literature is clear that a hash of an email or phone number is a consistent pseudonym, not anonymity, because the space of such identifiers can be enumerated. Research on re-identification from combinations of ordinary facts is consistent with the rule that small counts are never printed exactly.

Identity resolution decides which person a record belongs to. Every audience, every count and every result depends on it, so its errors flow into everything downstream. This note covers how records are attached to people, what hashing protects, and how the same reasoning shapes suppression and reporting.

Linking records that refer to the same entity has been studied since early work on linking vital records by computer (Newcombe et al., 1959). Any linkage method can make two errors: a false link joins records of two different people, and a missed link leaves two records of one person apart (Christen, 2012).

The classical theory compares a pair of records field by field and asks how much more likely the observed pattern of agreement γ\gamma is if the records match than if they do not (Fellegi and Sunter, 1969):

λ(γ)=m(γ)u(γ)=Pr⁡(γ∣match)Pr⁡(γ∣non-match)\lambda(\gamma) = \frac{m(\gamma)}{u(\gamma)} = \frac{\Pr(\gamma \mid \text{match})}{\Pr(\gamma \mid \text{non-match})}

Pairs with a high ratio are linked, pairs with a low ratio are not, and pairs in between go to review. Choosing the two thresholds fixes the rates of false and missed links. Probabilistic linkage tolerates disagreement on some fields in exchange for a false-link rate that has to be estimated. Deterministic linkage requires agreement on specified fields, which keeps false links rare at the cost of more missed links.

The right trade depends on what the links are used for. In Moonbrush’s case, links are used to count results and attribute them to campaigns. A false link can attach an inquiry to the wrong person and count it as coming from an ad that person never saw. A missed link loses a result, which makes response conservative. Moonbrush resolves deterministically, leaves ambiguous matches unattached, and does not rely on probabilistic matching by IP address or device for any count, which places it on the side of missed links. One setting leans the other way: the Broad strictness for client files accepts a single agreeing detail, for files where reach matters more than certainty.

Figure 1. How a record finds its person. The rule Moonbrush applies to graph deliveries, client files and site visitors. There is no score threshold and no guess: a record that fits more than one person is left unattached rather than joined to the wrong one. Postal address alone never attaches. Client files also set a strictness: how many distinct details must agree.

Schematic, not data

  • One durable ID per person. Identity providers can change their own identifiers at any rebuild. Moonbrush keeps its own durable ID and carries a record forward by its previous provider identifier or by a hashed email. A new ID is created only when no key matches, and a person missing from a delivery is marked absent, not deleted. See Identity resolution.
  • Strictness is a count, not a probability. For client files, strictness counts how many distinct details agree: one, two (the default) or three. An exact match on a primary email is accepted at every setting, and a postal address never matches on its own. See Matching.
  • Ambiguity attaches to no one. A record that agrees with more than one person is recorded as a conflict and left unattached.
  • The cost is shown first. The match rate for a file is shown in the preview, before any paid build runs.

Stable IDs matter beyond counting. Held-back assignment is keyed on the durable ID, so a person held back stays held back across monthly rebuilds, which a randomized comparison requires. See note 7.

4. What hashing does, and what it does not

Section titled “4. What hashing does, and what it does not”

SHA-256 is a cryptographic hash function specified in a federal standard (NIST, 2015). The same input always gives the same 256-bit output, and the output cannot feasibly be inverted by calculation. Moonbrush hashes emails, phone numbers and names after normalizing them (trimmed and lowercased; phones in E.164 form), as lowercase hexadecimal and unsalted, which is the form ad platforms require so that two parties holding the same email produce the same hash. See Delivery.

That consistency is also the limit. Hashing an identifier rarely anonymizes it in practice: when the set of possible inputs is small or structured, anyone can hash every candidate and look up the result (Demir et al., 2018). A ten-digit phone number has at most 101010^{10} possible values, a number small enough to enumerate:

∣{10-digit phone numbers}∣≤1010\left|\{\text{10-digit phone numbers}\}\right| \le 10^{10}

Email addresses are less regular but can be matched against lists of known addresses. A hashed identifier is a pseudonym, not an anonymous value.

  • Hash as early as possible. The site tag hashes an email in the visitor’s browser before anything is sent, and the collection server refuses any event that carries a raw email. Opt-outs on moonbrush.com are hashed in the browser too.
  • Keep the internal ID out of packages. Campaign packages and hashed exports carry an export-scoped row key, never Moonbrush’s internal person ID, so those files cannot be joined to each other through Moonbrush’s own key. A readable workspace export, a separate permissioned path for a client’s own systems, carries contact details and the Moonbrush ID. See What leaves the platform.
  • Withhold by count. People withheld for any reason appear in a package manifest only as counts.
  • Suppress on every path. Every export path withholds suppressed people, and fails closed if the suppression list cannot be read.

See What leaves the platform.

Ordinary facts identify people in combination. An analysis of 1990 census data found that 87% of the U.S. population was likely to be uniquely identified by five-digit ZIP code, gender and date of birth (Sweeney, 2000). Records stripped of names have been re-identified by linking them with other sources, including large, sparse datasets (Narayanan and Shmatikov, 2008), and legal scholarship has examined what this means for the promise of anonymization (Ohm, 2010). One formal response is k-anonymity, which requires each released combination of identifying facts to be shared by at least kk people (Sweeney, 2002).

The reporting rule that very small counts are not printed exactly is consistent with this research. See Reporting principles.

Global Privacy Control is a signal a browser sends to tell sites that the person does not want their data sold or shared, specified as a W3C Working Draft (Zimmeck et al., 2026). A study of its use found that most people surveyed would turn it on, and that many sites did not honor it when it was sent (Zimmeck et al., 2023).

Moonbrush stores the signal and the consent state with every event, and suppresses an identified person whose browser sent it. An opt-out from moonbrush.com is applied to every client list from the next nightly update.

Here Moonbrush makes the opposite choice from section 2.3. When an opt-out hash matches more than one candidate, every candidate is suppressed. In linking for counting, a false link can inflate a result, so Moonbrush prefers to miss links. In linking for suppression, a missed link would keep contacting a person who opted out, so Moonbrush prefers to suppress too many. In both cases the rule falls on the side of the error less likely to harm a person or overstate a result. See Privacy and permitted use.

Table 1. The same ambiguity, resolved in opposite directions for opposite purposes.

Purpose A record matches several people Error preferred Why
Counting and attribution Attach to no one; log the conflict Missed link A false link could count a result that did not happen
Suppression Suppress every candidate Over-suppression A missed link would keep contacting someone who opted out
  • Missed people. Deterministic matching misses people whose details have changed or were entered differently. The match rate makes the cost visible but does not remove it.
  • Hashing is not a contract. Hashing limits casual exposure. It does not protect against a recipient who already holds the identifiers, which is why what may be done with a package is governed by agreement and policy, not by the hash.
  • The graph is licensed. The consumer graph’s accuracy depends on its provider. Each monthly delivery is rehearsed on a sample, must produce zero duplicate people, and is refused if it would drop an unusual share of known people. See The consumer graph.
  1. What share of conflicts are resolved in a later delivery, and how is a resolution recorded?
  2. How is a durable ID carried forward when a person’s email changes?
  3. What is the threshold below which counts are not printed exactly?

Moonbrush’s identity rules follow the record-linkage literature’s central insight, that the two kinds of linking error have to be traded deliberately, and make that trade in the direction that protects counts and people. Its hashing rules follow the security literature’s warning that hashing an identifier is pseudonymization, and treat every hashed identifier as personal data.

  1. Christen, P. (2012). Data matching: Concepts and techniques for record linkage, entity resolution, and duplicate detection. Springer. doi.org/10.1007/978-3-642-31164-2
  2. Demir, L., Kumar, A., Cunche, M., & Lauradoux, C. (2018). The pitfalls of hashing for privacy. IEEE Communications Surveys & Tutorials, 20(1), 551–565. doi.org/10.1109/COMST.2017.2747598
  3. Fellegi, I. P., & Sunter, A. B. (1969). A theory for record linkage. Journal of the American Statistical Association, 64(328), 1183–1210. doi.org/10.1080/01621459.1969.10501049
  4. Narayanan, A., & Shmatikov, V. (2008). Robust de-anonymization of large sparse datasets. In Proceedings of the 2008 IEEE Symposium on Security and Privacy (pp. 111–125). IEEE. doi.org/10.1109/SP.2008.33
  5. Newcombe, H. B., Kennedy, J. M., Axford, S. J., & James, A. P. (1959). Automatic linkage of vital records. Science, 130(3381), 954–959. doi.org/10.1126/science.130.3381.954
  6. National Institute of Standards and Technology. (2015). Secure Hash Standard (SHS) (FIPS PUB 180-4). U.S. Department of Commerce. doi.org/10.6028/NIST.FIPS.180-4
  7. Ohm, P. (2010). Broken promises of privacy: Responding to the surprising failure of anonymization. UCLA Law Review, 57, 1701–1777. papers.ssrn.com/abstract=1450006
  8. Sweeney, L. (2000). Simple demographics often identify people uniquely (Data Privacy Working Paper 3). Carnegie Mellon University. dataprivacylab.org/projects/identifiability/paper1.pdf
  9. Sweeney, L. (2002). k-anonymity: A model for protecting privacy. International Journal of Uncertainty, Fuzziness and Knowledge-Based Systems, 10(5), 557–570. dataprivacylab.org/projects/kanonymity/index.html
  10. Zimmeck, S., Wang, O., Alicki, K., Wang, J., & Eng, S. (2023). Usability and enforceability of Global Privacy Control. Proceedings on Privacy Enhancing Technologies, 2023(2), 265–281. doi.org/10.56553/popets-2023-0052
  11. Zimmeck, S., Snyder, P., Brookman, J., & Zucker-Scharff, A. (Eds.). (2026, September 24). Global Privacy Control (GPC). W3C Working Draft. www.w3.org/TR/gpc/

Every figure on these pages carries the date it was measured. See Published figures.

© 2026 Moonbrush Inc. Moonbrush, atlas, stage and Gravity are pending trademarks of Moonbrush Inc.