Telefonnummern und E-Mail-Adressen in Google Tabellen hashen

8apps-Team·

Google Tabellen hat keine eingebaute SHA-256-Funktion. So hashst du eine Kundenliste richtig – und warum dieselbe Nummer zwei verschiedene Hashes braucht.

Alle denken das falsch herum. Einen SHA-256-Digest zu erzeugen kostet vier Zeilen Apps Script. Einen Match aus einer Werbeplattform zu holen kostet Normalisierung – und an der Normalisierung sterben Listen.

Google sagt es in der eigenen API-Dokumentation unmissverständlich: "If the contact information is not correctly formatted before hashing, the API still accepts the hashed information, but it can't be matched with a customer."

Der Upload gelingt. Was scheitert, ist die Match-Rate. Und nichts sagt es dir.

Dieser Leitfaden behandelt beide Hälften – wie du in Google Tabellen tatsächlich einen Hash erzeugst und welche plattformspezifischen Normalisierungsregeln darüber entscheiden, ob er irgendetwas trifft. Für die erste Hälfte gibt es vier Wege. Der kürzeste ist ein Add-on, das in einer Funktion normalisiert und hasht – Weg 1 weiter unten –, und der Rest dieser Seite ist die Begründung, warum die Normalisierung der Teil ist, den man richtig machen sollte.


Zuerst: Google Tabellen hat keine Hash-Funktion

Googles veröffentlichte Funktionsliste umfasst siebzehn Kategorien – Datum, Technisch, Finanzen, Text, Mathematik und so weiter. Es gibt kein SHA256, kein MD5, kein HASH, kein DIGEST. Die Kategorie Technisch enthält Basisumrechnungen und komplexe Zahlen und nichts Kryptografisches.

Jeder Weg ist also ein Umweg. Es gibt vier, und sie sind nicht gleich gut:

WegWann er passtUrteil
Ein Add-on, das Hash-Funktionen in die Tabelle bringtDu hast eine echte Kundenliste vorzubereiten und willst die Normalisierung erledigt habenEmpfohlen
Eigenes Apps Script als benutzerdefinierte FunktionDu willst den Code besitzen oder brauchst einen Algorithmus bzw. eine Regel, die kein Add-on umsetztIn Ordnung, mit Sorgfalt
Ein Web-HasherDu prüfst eine einzelne TestzeichenfolgeNicht für eine Liste
Gar nicht hashenDeine Plattform akzeptiert Klartext und deine Richtlinie erlaubt esLegitim

Der Rest dieses Abschnitts geht sie der Reihe nach durch. Die Normalisierungsregeln weiter unten gelten unabhängig davon, welchen Weg du wählst – sie entscheiden über deine Match-Rate, und kein Weg befreit dich von ihnen.


Weg 1: ein Add-on, das die Funktionen in die Tabelle bringt

Das ist der Weg, zu dem du greifen solltest, und der Grund ist genau das Argument dieser Seite. Einen Digest zu erzeugen ist trivial. Die Eingabe korrekt zu normalisieren entscheidet darüber, ob der Upload überhaupt jemanden trifft – und diesen Schritt kann ein Add-on für dich übernehmen, je Eingabetyp, auf jeder Zeile gleich.

Hash Data teilt die Aufgabe entsprechend auf:

FunktionWas sie tut
=HASHEMAIL(email, [algorithmus])Entfernt Leerzeichen, schreibt klein, hasht dann
=HASHPHONE(telefon, [algorithmus])Bringt die Nummer ins E.164-Format und hasht sie – ein Schritt, statt REGEXREPLACE in eine Digest-Formel zu verketten
=HASH(wert, [algorithmus])Hasht den Wert exakt wie übergeben – keine Normalisierung, Groß- und Kleinschreibung zählt

Vier Dinge, die dir das gegenüber einem selbst geschriebenen Skript bringt:

  • Die Normalisierung steckt in der Funktion, nicht in einer Hilfsspalte, die du in jeder neuen Tabelle neu aufbauen musst.
  • Keine 30-Sekunden-Grenze für benutzerdefinierte Funktionen, um die herum du konstruieren musst – warum das bei einer echten Liste zählt, steht in Weg 2.
  • Deine Liste bleibt in der Tabelle. Nichts wird in eine fremde Website eingefügt.
  • SHA3-256 ist verfügbar, was computeDigest() in Apps Script selbst nicht anbietet.

Ein Vorbehalt, klar gesagt, weil er über die Funktionswahl entscheidet. =HASHPHONE() normalisiert auf E.164 – Ziffern mit führendem +. Das entspricht dem, was Google Ads dokumentiert. Metas dokumentiertes Beispiel geht in die andere Richtung: nur Ziffern, kein +. Für einen Meta-Upload normalisierst du die Nummer also selbst mit =REGEXREPLACE(A2, "[^0-9]", "") und hasht diese Zeichenfolge mit =HASH(). Eine Funktion bedient nicht beide Plattformen, weil die Plattformen sich nicht einig sind – denselben Punkt macht die Vergleichstabelle weiter unten.

Der kostenlose Tarif umfasst 100 Hash-Aufrufe pro Tag, der kostenpflichtige hebt die Grenze auf.

Hash Data im Google Workspace Marketplace installieren


Weg 2: die benutzerdefinierte Funktion selbst schreiben

Wenn du den Code lieber selbst besitzt, ist das hier alles. Öffne Erweiterungen → Apps Script, füge das ein, speichere und nutze =SHA256(A2) in der Tabelle.

/**
 * Gibt den SHA-256-Digest der Eingabe als Hex in Kleinbuchstaben zurueck.
 * Nimmt eine einzelne Zelle oder einen Bereich entgegen.
 * @customfunction
 */
function SHA256(input) {
  if (Array.isArray(input)) {
    return input.map(function (row) {
      return row.map(function (cell) { return SHA256(cell); });
    });
  }

  if (input === '' || input === null || input === undefined) return '';

  var bytes = Utilities.computeDigest(
    Utilities.DigestAlgorithm.SHA_256,
    String(input),
    Utilities.Charset.UTF_8
  );

  return bytes
    .map(function (b) { return ((b < 0 ? b + 256 : b)).toString(16).padStart(2, '0'); })
    .join('');
}

Zwei Dinge bringen hier viele zu Fall, und beide lohnen sich zu verstehen, selbst wenn du das Skript nie selbst schreibst.

computeDigest() liefert ein vorzeichenbehaftetes Byte-Array zurück, keine Hex-Zeichenfolge. Apps Script gibt Bytes im Java-Stil mit Vorzeichen zurück, alles oberhalb von 0x7F kommt also negativ an. Genau das repariert b < 0 ? b + 256 : b. Lässt du es weg, bekommst du einen Digest voller --Zeichen, den keine Plattform akzeptiert. Lässt du padStart(2, '0') weg, verlierst du still führende Nullen einzelner Bytes und erzeugst einen Digest mit weniger als 64 Zeichen, der auf sehr schwer erkennbare Weise falsch ist.

Eine benutzerdefinierte Funktion muss innerhalb von 30 Sekunden zurückkehren, sonst zeigt die Zelle #ERROR!. Eine Variante pro Zelle – eine Formel in jeder Zeile – bricht bei einer echten Kundenliste zusammen. Deshalb prüft die Funktion oben zuerst auf ein Array: So geschrieben, kannst du =SHA256(A2:A5000) in eine einzige Zelle setzen und dir die ganze Spalte als ein Array zurückgeben lassen.


Weg 3: ein Web-Hasher

Über diesen Weg solltest du am gründlichsten nachdenken, denn er ist der naheliegendste und der einzige mit einem Offenlegungsproblem.

Eine Kundenliste in eine Website einzufügen ist eine Übermittlung personenbezogener Daten an denjenigen, der diese Website betreibt. Der Seite ist in der Regel nicht anzusehen, ob das Hashen in deinem Browser oder auf ihrem Server passiert – und die Antwort ist von erheblicher Bedeutung. Für eine einzelne Testzeichenfolge in Ordnung; weiter unten auf dieser Seite steht eine, die du dafür verwenden solltest. Für eine Liste echter Kunden: nein.


Weg 4: gar nicht hashen

Die vergessene Möglichkeit. Google Ads akzeptiert Kundendaten im Klartext und hasht sie vor dem Upload, und TikTok dokumentiert, dass es "accepts both hashed and original values."

Wenn dein Grund fürs Hashen also eine Richtlinie oder ein Vertrag ist, ist Hashing die Antwort. Wenn du angenommen hast, es sei verpflichtend, ist es das häufig nicht – und Vorab-Hashen bedeutet, dass du die Normalisierung besitzt, samt jedem Fehler darin, statt der Plattform. Das ist es wert, gewusst zu werden, bevor du eine Pipeline darum herum baust.


Dann: normalisieren, und zwar je Plattform

Diesen Teil überspringen die meisten Leitfäden, und er ist der Grund, warum Match-Raten einbrechen.

Google Ads

Customer Match dokumentiert für gehashte Spalten: alles kleinschreiben, Leerzeichen entfernen, "Format phone numbers using the E.164 format" und – ausdrücklich – "Include the country code and '+' sign."

Google dokumentiert eine reine Gmail-Regel an zwei Stellen, und sie sind nicht identisch – das sollte man wissen, bevor man eine davon in eine Pipeline kopiert.

Die Seite zur Customer Match-Datendatei sagt nur: "Remove all periods (.) that precede the domain name in gmail.com and googlemail.com email addresses." Punkte, sonst nichts.

Die Customer Match-API-Seite geht weiter, aber unter einer Überschrift, die auf Enhanced Conversions eingegrenzt ist: Punkte aus dem Nutzernamen entfernen und das Pluszeichen samt allem, was danach kommt. Das durchgerechnete Beispiel dort lautet Jane.Doe+Shopping@googlemail.comjane.doe+shopping@googlemail.com (kleingeschrieben) → janedoe@googlemail.com.

Die Plus-Suffix-Hälfte ist also für Enhanced Conversions dokumentiert, nicht für den Upload einer Kundenliste. Wenn du eine Zielgruppenliste baust, ist die Punkte-Regel diejenige, die Google für diese Aufgabe tatsächlich dokumentiert. Worin beide übereinstimmen: Das gilt ausschließlich für gmail.com und googlemail.com. Es auf jede Domain anzuwenden ist ein eigener Fehler – viele Mailsysteme behandeln jane.doe@ und janedoe@ als verschiedene Personen.

Meta

Meta dokumentiert etwas anderes. Für E-Mail: "Trim any leading and trailing spaces. Convert all characters to lowercase." Überhaupt keine Gmail-Punkte-Regel.

Für Telefon: "Remove symbols, letters, and any leading zeros," dazu "Always include the country code as part of your customers' phone numbers." Metas eigenes durchgerechnetes Beispiel lautet (650)555-121216505551212 – Ländervorwahl, nur Ziffern, kein Pluszeichen.

Dieselbe Telefonnummer ergibt also zwei verschiedene Hashes

Google AdsMeta
Telefon, dokumentiertE.164, "include the country code and '+' sign""Remove symbols… and any leading zeros"; Beispiel → 16505551212
Gmail-Punkte und +-SuffixPunkte entfernt für gmail.com / googlemail.com; die +-Suffix-Regel ist für Enhanced Conversions dokumentiertNicht dokumentiert
Kodierung"Use hex SHA256""HEX representations… using lowercase for A through F"

Eine gehashte Spalte kann nicht beide Plattformen bedienen. Wenn du bisher eine wiederverwendet hast, ist das deine Match-Rate.

TikTok ist der Ausreißer

TikTok dokumentiert deutlich weniger: "MD5 and SHA256 encryption is supported. The content of the file before encryption needs to be in all uppercase or lowercase." Es ist keine E.164-Anforderung veröffentlicht, und es werden sowohl gehashte als auch originale Werte akzeptiert. Nimm nicht an, dass Googles Regeln dort gelten.


Die Formeln, in der Reihenfolge ihrer Anwendung

In einer Hilfsspalte normalisieren, die Hilfsspalte hashen, dann nur den Digest behalten.

SchrittFormel
E-Mail, beide Plattformen=LOWER(TRIM(A2))
Geschütztes Leerzeichen entfernen, das TRIM() übersieht=TRIM(SUBSTITUTE(A2, CHAR(160), " "))
Gmail-Punkte und +-Suffix, nur Google Ads – siehe den Geltungsvorbehalt oben (angewendet auf B2, die kleingeschriebene E-Mail)=IF(REGEXMATCH(B2, "@(gmail|googlemail)\.com$"), SUBSTITUTE(REGEXREPLACE(REGEXEXTRACT(B2, "^[^@]+"), "\+.*$", ""), ".", "") & REGEXEXTRACT(B2, "@.*$"), B2)
Telefon, nur Ziffern (Meta)=REGEXREPLACE(A2, "[^0-9]", "")
Telefon, E.164 (Google Ads)="+" & REGEXREPLACE(A2, "[^0-9]", ""), sobald du sicher bist, dass die Ländervorwahl vorhanden ist

Die letzte Zeile trägt einen Vorbehalt, der laut ausgesprochen gehört: Einer nationalen Nummer ein + voranzustellen erzeugt keine gültige E.164-Nummer. Aus 07700 900461 wird +7700900461, was falsch ist und nicht matchen wird. Die Ländervorwahl muss tatsächlich da sein.


Die Fehlerbilder, in der Reihenfolge ihres Auftretens

  1. Deine Tabelle zerstört die Daten, bevor du hashst. Eine 16-stellige Zahl wird zur wissenschaftlichen Notation, 07700 900461 verliert die führende Null, +44… wird als Formel gelesen. Formatiere die Spalte als Klartext, bevor irgendetwas darin landet – nachträgliches Reparieren ist Datenverlust, keine Formatierung.
  2. Groß- und Kleinschreibung sowie Leerzeichen. John@ und john@ sind verschiedene Digests. Ebenso john@x.com und john@x.com mit einem Leerzeichen am Ende aus einem CSV-Export. Und TRIM() entfernt kein geschütztes Leerzeichen – genau das, was ein Copy-and-paste von einer Webseite hinterlässt.
  3. Den Anzeigewert hashen. (650) 555-1212 ist nicht 16505551212. Ist die Zelle als Telefonnummer formatiert, sind das, was du siehst, und das, was du hashst, verschiedene Zeichenfolgen.
  4. Doppeltes Hashen. Die Formel über eine Spalte laufen lassen, die bereits Hashes enthält. Einfache Prüfung: Ein SHA-256-Hex-Digest ist immer exakt 64 Zeichen aus 0-9a-f, =LEN(B2)=64 fängt das ab – und Abschneidungen gleich mit.
  5. Falsche Kodierung. Ein Base64-Digest ist ein gültiger Hash der richtigen Eingabe und wird trotzdem nicht matchen. Etliche verbreitete Copy-and-paste-Schnipsel nutzen standardmäßig MD5 und Base64.

Vor dem Upload prüfen

Meta veröffentlicht den erwarteten Digest für john_smith@gmail.com:

62a14e44f765419d10fea99367361a727c12365e2520f32218d505ed9aa0f62f

Hashe genau diese Zeichenfolge mit deiner Formel. Kommt nicht exakt dieser Wert zurück, repariere die Formel – nicht die Liste. Das kostet dreißig Sekunden und ist der einzige Test, der "mein Hashing ist kaputt" von "meine Liste ist schlecht" unterscheidet, was von außen sonst ununterscheidbar ist.


Ein ehrliches Wort zum Datenschutz

Hashing ist Pseudonymisierung, keine Anonymisierung. Die DSGVO klärt das in Erwägungsgrund 26: "Einer Pseudonymisierung unterzogene personenbezogene Daten, die durch Heranziehung zusätzlicher Informationen einer natürlichen Person zugeordnet werden könnten, sollten als Informationen über eine identifizierbare natürliche Person betrachtet werden." Die Leitlinien 01/2025 des Europäischen Datenschutzausschusses zur Pseudonymisierung bauen genau auf diesem Ausgangspunkt auf.

Ein ungesalzener Telefon-Hash lässt sich per Brute Force durchgehen – der Zahlenraum ist klein genug, um ihn vollständig auszuschöpfen. Und salzen kannst du ihn nicht, weil genau das den Abgleich der Plattform verhindert. Gehashte Kundendaten sind weiterhin Kundendaten. Behandle sie so.

Wenn du fertig bist: gehashte Spalte kopieren, Inhalte einfügen als "Nur Werte", Rohspalte löschen.


Das Ganze, der Reihe nach

Welchen Weg du auch gewählt hast, die Abfolge ist dieselbe:

  1. Spalte als Klartext formatieren, bevor die Daten darin landen.
  2. In einer Hilfsspalte normalisieren, nach den Regeln der Plattform, zu der du hochlädst – nicht der anderen.
  3. Hilfsspalte hashen, Hex-SHA-256, sofern die Plattform nichts anderes sagt.
  4. Eine bekannte Zeichenfolge testen gegen Metas veröffentlichten Digest, bevor du der Spalte traust.
  5. =LEN(B2)=64 prüfen über den gesamten Bereich, um Abschneidungen und doppeltes Hashen zu finden.
  6. Inhalte einfügen als "Nur Werte", Rohspalte löschen und hochladen.

Die Schritte 2 und 3 sind die, die Hash Data zu einer einzigen Funktion zusammenfasst – =HASHEMAIL() für E-Mail, =HASHPHONE() für Telefonnummern im E.164-Format, =HASH() für alles, was du selbst normalisiert hast. Unterstützt werden SHA256, MD5, SHA1, SHA512 und SHA3-256, und alles läuft innerhalb deiner Tabelle. Der kostenlose Tarif umfasst 100 Hash-Aufrufe pro Tag, der kostenpflichtige hebt die Grenze auf.


Quellen

Plattformspezifikationen geprüft am 20. August 2026. Werbeplattformen überarbeiten diese Seiten; prüfe die Quelle vor einem großen Upload.


Weiterführende Artikel