Skip to main content
All personally identifiable information (PII) uploaded to Narrative must be pseudonymized using cryptographic hash functions. This guide walks you through formatting and hashing email addresses and phone numbers before uploading them to the platform.
To understand why Narrative requires hashed identifiers rather than raw PII, see Data Pseudonymization.

Prerequisites

Before you begin, ensure you have:
  • Your ID list saved as a single-column CSV file
  • Access to one of the following: Google Sheets, a command line terminal, or the Touchless PII Hasher app

Choose your method

MethodBest forRequirements
Touchless PII HasherQuick, one-off hashingWeb browser only
Google SheetsSmall lists (under 10,000 rows)Google account
Command lineLarge lists, automationTerminal access

Hashing email addresses

Pre-formatting requirements

Hash functions are case-sensitive and whitespace-sensitive. Before hashing, you must normalize your email addresses:
RuleExampleResult
Lowercase all text[email protected][email protected]
Remove leading/trailing whitespace [email protected] [email protected]
Remove + aliases and everything after[email protected][email protected]
Remove extra periods in username[email protected][email protected]
Skipping pre-formatting will result in different hash values, preventing matches with other datasets. A single extra space or uppercase letter produces a completely different hash.

Supported hash algorithms

Narrative supports three hash algorithms. For maximum correspondence with other datasets, we recommend generating all three:
AlgorithmOutput lengthExample hash of [email protected]
MD532 characters29a1df4646cb3417c19994a59a3e022a
SHA-140 characterse1e8d3e4a336d4f9dc63b70a534ff10834471556
SHA-25664 characters06a240d11cc201676da976f7b49341181fd180da37cbe40a77432c0a366c80c3

Method 1: Touchless PII Hasher (fastest)

The Touchless PII Hasher is a free web app that handles formatting and hashing automatically. Your data never leaves your browser.
1

Open the app

2

Upload your file

Drag and drop your CSV file or click to browse.
3

Download the results

The app automatically formats and hashes your data. Download the resulting file.

Method 2: Google Sheets (small lists)

For lists under 10,000 rows, use Narrative’s Hashing Functions spreadsheet which automatically handles pre-formatting and all three hash algorithms.
1

Make a copy of the template

Open the Hashing Functions spreadsheet and click Make a copy when prompted.
2

Paste your email list

Copy your list of emails and paste them starting in cell A4.
3

Wait for processing

The spreadsheet may take a few minutes to compute, depending on list size.
4

Download the results

Navigate to the tab titled DOWNLOAD_THIS_SHEET_AS_.CSV_FILE. Go to File > Download > Comma-separated values (.csv, current sheet).

Method 3: Command line (large lists)

For large lists or automation, use the command line. Narrative provides a hashing script, or you can use standard Unix tools.
Option A: Use Narrative’s hashing script
1

Download the script

Download hashingFunction.py and save it to your ~/bin directory.
2

Make it executable

chmod +x ~/bin/hashingFunction.py
3

Run the script

~/bin/hashingFunction.py < input.csv > output.csv
Option B: Use standard Unix toolsFor a quick one-liner that handles pre-formatting and generates SHA-256 hashes:
cat emails.csv | tr '[:upper:]' '[:lower:]' | sed 's/+[^@]*//g' | \
  while read email; do echo -n "$email" | shasum -a 256 | cut -d' ' -f1; done > hashed.csv
To generate all three hash formats:
cat emails.csv | tr '[:upper:]' '[:lower:]' | sed 's/+[^@]*//g' | \
  while read email; do
    echo "$(echo -n "$email" | md5),$(echo -n "$email" | shasum -a 1 | cut -d' ' -f1),$(echo -n "$email" | shasum -a 256 | cut -d' ' -f1)"
  done > hashed.csv
Never direct output to the same file as input. This will delete your data:
# DO NOT DO THIS
hashingFunction.py < emails.csv > emails.csv  # Data will be lost!

Hashing phone numbers

Phone numbers follow a similar process, but with different pre-formatting rules.

Pre-formatting requirements

RuleExampleResult
Remove all non-numeric characters+1 (555) 123-456715551234567
Include country code555-123-4567 (US)15551234567
Remove leading zeros (except country code)0555-123-456715551234567

Using Google Sheets for phone numbers

Use Narrative’s Phone Hashing Functions spreadsheet which automatically strips non-numeric characters before hashing. Follow the same steps as email hashing above.

Using command line for phone numbers

cat phones.csv | tr -cd '0-9\n' | \
  while read phone; do
    echo "$(echo -n "$phone" | md5),$(echo -n "$phone" | shasum -a 1 | cut -d' ' -f1),$(echo -n "$phone" | shasum -a 256 | cut -d' ' -f1)"
  done > hashed_phones.csv

Verify your output

Before uploading, verify your hashing is correct using this test data: Test email: [email protected]
AlgorithmExpected hash
SHA-25606a240d11cc201676da976f7b49341181fd180da37cbe40a77432c0a366c80c3
MD529a1df4646cb3417c19994a59a3e022a
SHA-1e1e8d3e4a336d4f9dc63b70a534ff10834471556
If your hashes match, your implementation is correct.

Uploading your hashed list

Once your list is hashed:
  1. Ensure your file is in CSV format
  2. Navigate to your dataset in Narrative
  3. Upload the hashed file
For detailed upload instructions, see Connecting Data Sources.

Troubleshooting

IssueCauseSolution
Hashes don’t match expected valuesPre-formatting not appliedVerify lowercase, whitespace removal, and alias stripping
Google Sheets is slow or unresponsiveList too largeUse command line method for lists over 10,000 rows
Different hashes for same emailInconsistent formattingEnsure all emails go through the same pre-formatting pipeline
Command not found (Mac/Linux)Script not in PATHUse full path to script or add ~/bin to PATH
PowerShell security errorExecution policyRun Set-ExecutionPolicy -Scope CurrentUser RemoteSigned