Hashing in Excel

Prepare personal data in a spreadsheet to match your Filament sources.

On this page

When you turn on PII hashing for a source, Filament swaps personal fields — emails, names, phone numbers — for a one-way hash before the data ever lands in your warehouse. The same person always produces the same hash, so you can still join and count them across sources without storing a single raw value.

If some of that data lives in a spreadsheet, you’ll want to hash it before you upload, so those rows match the hashes Filament produces from Stripe, your CRM, and everywhere else. The whole trick is to use exactly the same recipe we do — this guide walks you through it in Excel, step by step.

The recipe we use

Under the hood, every value Filament hashes goes through the same four steps:

  1. Take the raw text value. For email addresses, trim the surrounding whitespace and lowercase the whole thing first — so Tom@X.com and tom@x.com hash identically. Every other field is hashed exactly as stored, with no trimming and no case changes.
  2. Stick your organisation’s hashing salt on the end of the value: value + salt.
  3. Run SHA-256 over that string, encoded as UTF-8.
  4. Encode the result as Base64 — the standard variant, with = padding, not the URL-safe one.

Put together, the output for any value is base64( sha256( value + salt ) ). Every part matters: the wrong salt, hex instead of Base64, or a stray space on an email will leave you with hashes that never line up.

Step 1: Find your hashing salt

Your salt is unique to your organisation. Open your Account page, find the Data hashing section, and copy the salt — it’s a 64-character string of letters and numbers. Keep it somewhere handy; you’ll paste it into the formula in a moment.

Treat the salt like a password. Anyone who has it and a hashed value can test guesses against it, so don’t share it outside your team. And if you belong to more than one Filament organisation, double-check you’ve grabbed the salt from the one you’ll be uploading this data to.

Step 2: Turn on Python in Excel

Excel can reproduce our hashing exactly using Python in Excel, which gives you Python’s hashlib library right inside a cell. It’s generally available in Microsoft 365 (Business and Enterprise on the Current Channel for Windows and Mac; in preview for Personal and Family), so for most work accounts it’s already there.

You don’t need to install anything — just start a formula with =PY( and Excel switches that cell into Python mode. The steps below drop straight into those =PY(...) cells.

Step 3: Hash an email column

Say your email addresses are in column A, starting at A2. Click cell B2, paste in the formula below, and swap PASTE_YOUR_SALT_HERE for the salt you copied in Step 1:

=PY(
import hashlib, base64
salt = "PASTE_YOUR_SALT_HERE"
value = str(xl("A2")).strip().lower()
base64.b64encode(hashlib.sha256((value + salt).encode("utf-8")).digest()).decode()
)

Press Enter, then fill the formula down the column just like any other. The xl("A2") reference moves down row by row, so each cell hashes its own email. The .strip().lower() is what trims and lowercases the address to match what we do on ingest.

Step 4: Hash names, phone numbers, and other fields

Non-email fields are hashed exactly as they’re stored — no trimming, no lowercasing. For those, use the same formula but drop the .strip().lower():

=PY(
import hashlib, base64
salt = "PASTE_YOUR_SALT_HERE"
value = str(xl("A2"))
base64.b64encode(hashlib.sha256((value + salt).encode("utf-8")).digest()).decode()
)

Everything else is the same: paste it into the first cell, fix the salt, and fill it down the column.

Step 5: Hash a whole column at once (optional)

If you’d rather not fill down cell by cell, you can hash an entire range in one formula. Point it at the range and apply the same logic to each cell:

=PY(
import hashlib, base64
salt = "PASTE_YOUR_SALT_HERE"
def filament_hash(v):
    v = str(v).strip().lower()
    return base64.b64encode(hashlib.sha256((v + salt).encode("utf-8")).digest()).decode()
xl("A2:A1000").iloc[:, 0].apply(filament_hash)
)

This spills the hashed values down as a single column. Keep the .strip().lower() for emails; remove it for any other field.

Step 6: Check one value before you trust the rest

Before you hash thousands of rows, prove the recipe matches on a single value you can already check. Pick a person who appears in both the spreadsheet and an already-hashed Filament source, hash their email in Excel, and confirm the string is character-for-character identical to the one in your warehouse.

If it matches, the rest of the column will too, and you’re ready to upload. If it doesn’t, re-check the salt, make sure you’re getting Base64 and not hex, and confirm you trimmed and lowercased the email.

A few things to watch for

  • Numbers stored as numbers. A phone number or ID held as a numeric cell can stringify as 61400000000.0, with a trailing .0. Format the column as text (or cast it deliberately) so the string you hash matches what your other source sends.
  • Blank cells. Filament hashes an empty value as an empty string, but Excel turns empty cells into "None" via str(). Filter them out, or coalesce them to "", if you need blanks to line up.
  • Privacy check. Python in Excel runs in Microsoft’s cloud, so cell values are sent to Microsoft to be calculated. It’s the same personal data you’re about to upload to Filament anyway, but make sure that’s acceptable under your own data policies first.

Need a hand with this?

Contact support