Masking PII data for display with AMPscript

There are many use cases, especially in the transactional space, where sometimes there is a need to display partially masked data to the end-user – exactly in the same way as you would see it when logging in to Marketing Cloud, when the system tells you which email address it sent the verification code to:

Please note that this article is not about anonymizing/masking data inside Marketing Cloud to prevent the users from seeing it – it rather describes how to partially hide some of the PII data when displaying it to your end-users (customers). If you’re after securing data inside Marketing Cloud, there is a great series of articles available at Devs United.

Masking PII data with AMPscript

The logic behind partially masking PII data for display is quite simple: you need to decide how much of a string should be hidden and then replace part of it with asterisks or other symbols. Let’s make an assumption that we want to hide all but the first and the last character in a string. This is how we can build the script to handle this:

Pull the Data Extension field that needs to be masked. In the script below I have used AttributeValue(), but you can use a Lookup() or any other function required to pull the data.

set @text = AttributeValue("email")

Check the length of the string. Here we will use the Length() function.

set @length = Length(@text)

Set the number of characters to be masked / number of characters to be shown by subtracting the number of characters to be masked from the length of the original string. We will use the Subtract() function to subtract the number of characters to be shown from the number of characters in the original string.

set @subtract = subtract(@length,2)

From the original string, extract the part that should be masked.

set @substring = Substring(@text,2,@subtract)

Prepare a string with the correct number of asterisks to replace a part of the original string.

  for @i = 1 to @length do
      set @asterisks = concat(@asterisks,"*")
  next @i

Replace the content of the original string with asterisks using the Substring() function.

set @maskedText = replace(@text, @substring, @asterisks)

Here is the full code:

%%[
/* pull the field to be masked from a data extension */
set @text = AttributeValue("email")
/* check the length of the string */
set @length = Length(@text)
/* count the number of characters to mask.
it also controls how many characters will not be masked.
currently set to 2, change to more if needed */
set @subtract = subtract(@length,2)
/* extract the string to be masked */
set @substring = Substring(@text,2,@subtract)
/* prepare a string of asterisks with the same length */
for @i = 1 to @length do
set @asterisks = concat(@asterisks,"*")
next @i
/* replace content of the original string with asterisks */
set @maskedText = replace(@text, @substring, @asterisks)
]%%
%%=v(@maskedtext)=%%<br>

Masking an email address

The logic gets a little bit more complicated when it comes to masking email addresses – you probably don’t want to mask the whole email, but a part of the username and a part of the domain, leaving the at symbol in its place. Let’s make an assumption that we want to hide all but the first and the last character in the username and half of the characters in the domain (you can adjust those settings to fit your use case). This is how we can build the script to handle this:

Pull the Data Extension field with the email address that you want to mask.

set @email = AttributeValue("email")

Find the position of the @ sign in the string

set @at = indexOf(@email, "@")

Extract the username portion of the email address

set @username = Substring(@email,1, Subtract(@at,1))

Check the length of the username string

set @lenUsername = Length(@username)

Set the number of characters to be masked / number of characters to be shown in the username part of the email by subtracting the number of characters to be masked from the length of the original string

set @lenSubtract = subtract(@lenusername,2)

From the original username part of the string, extract the part that should be masked.

set @usernameSubstring = Substring(@username,2,@lenSubtract)

Prepare a string with a correct number of asterisks to replace a part of the original username string.

  for @i = 1 to @lenSubtract do
      set @usernameAsterisks = concat(@usernameAsterisks,"*")
  next @i

Extract the domain portion of the email address

set @domain = Substring(@email,add(@at,1))

Check the length of the domain string

set @lenDomain = Length(@domain)

Calculate the number of characters to be masked. I have decided to mask exactly half of the characters in the domain. For that purpose, we will divide the length of the domain in half and use the FormatNumber() function to make sure it’s rounded up to a whole number.

set @halfDomain = FormatNumber(Divide(@lendomain,2),"F0")

From the original domain part of the string, extract the part that should be masked.

set @domainSubstring = Substring(@domain,2,@halfdomain)

Prepare a string with a correct number of asterisks to replace a part of the original domain string.

  for @i = 1 to @halfdomain do
      set @domainAsterisks = concat(@domainAsterisks,"*")
  next @i

Replace content of the original email string with asterisks:

set @maskedEmail = concat(replace(@username, @usernameSubstring, @usernameAsterisks),"@",replace(@domain, @domainSubstring, @domainAsterisks))

Here is the full code:

%%[
/* pull the field to be masked from a data extension */
set @email = AttributeValue("email")
/* find the position of the first occurrence of an @ sign in the string */
set @at = indexOf(@email, "@")
/* extract the username portion of the email address */
set @username = Substring(@email,1, Subtract(@at,1))
/* check the length of the username */
set @lenUsername = Length(@username)
/* count the number of characters to mask in the username.
it also controls how many characters will not be masked.
currently set to 2, change to more if needed */
set @lenSubtract = subtract(@lenusername,2)
/* extract the string to be masked in the username */
set @usernameSubstring = Substring(@username,2,@lenSubtract)
/* prepare a string of asterisks with the same length as extracted part of username */
for @i = 1 to @lenSubtract do
set @usernameAsterisks = concat(@usernameAsterisks,"*")
next @i
/* extract the domain portion of the email address */
set @domain = Substring(@email,add(@at,1))
/* check the length of the domain */
set @lenDomain = Length(@domain)
/* calculate the number of characters equal to half of the domain length */
set @halfDomain = FormatNumber(Divide(@lendomain,2),"F0")
/* extract the string to be masked in the domain */
set @domainSubstring = Substring(@domain,2,@halfdomain)
/* prepare a string of asterisks with the same length as extracted part of domain */
for @i = 1 to @halfdomain do
set @domainAsterisks = concat(@domainAsterisks,"*")
next @i
/* replace content of the original email string with asterisks */
set @maskedEmail = concat(replace(@username, @usernameSubstring, @usernameAsterisks),"@",replace(@domain, @domainSubstring, @domainAsterisks))
]%%
%%=v(@maskedEmail)=%%

Questions? Comments?

Leave a comment below or email me at zuzanna@sfmarketing.cloud.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s