Last active
July 13, 2021 00:25
-
-
Save rpbeukes/766aa2a0198e5ddf1ccce4a0d4b6734c to your computer and use it in GitHub Desktop.
Redact/Mask the email address eg: some@gmail.com => s**e@g****.com
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Redact/Mask the email address eg: some@gmail.com => s**e@g****.com | |
/// </summary> | |
public class EmailRedactor | |
{ | |
/// <summary> | |
/// eg: "some@gmail.com" => "s**e@g****.com" | |
/// </summary> | |
/// <param name="email"></param> | |
/// <returns></returns> | |
public string Redact(string email) | |
{ | |
try | |
{ | |
if (string.IsNullOrWhiteSpace(email)) | |
return email; | |
// look for first occurrence of '@' in email | |
char[] chDelimiter = { '@' }; | |
var split = email.Split(chDelimiter, 2); | |
string redactedEmail = null; | |
if (split.Length == 2) | |
{ | |
// the '@' was detected and we have a split of 2 parts | |
var emailName = split[0]; | |
var domain = split[1]; | |
string domainExtension = null; | |
// find th last '.' as part of the domain | |
if (domain.LastIndexOf('.') >= 0) | |
{ | |
// found the last occurrence of '.' | |
domainExtension = domain.Substring(domain.LastIndexOf('.')); // eg: "domain.com" => ".com" | |
// remove the domain extention from the existing domain string eg: "domain.com" => "domain" | |
domain = domain.Substring(0, domain.Length - domainExtension.Length); | |
} | |
// everything before left of '@' | |
redactedEmail = emailName[0].ToString(); // first letter of email name | |
// add the '*' | |
redactedEmail += emailName.Length >= 2 ? new string('*', emailName.Length - 2) | |
: string.Empty; | |
redactedEmail += emailName.Length > 1 ? emailName[emailName.Length - 1].ToString() | |
: string.Empty; | |
redactedEmail += '@'; | |
// everything right of '@' | |
redactedEmail += domain[0]; // first letter of domain | |
redactedEmail += new string('*', domain.Length - 1); // fill up with '*' | |
redactedEmail += (domainExtension ?? string.Empty); // add domain extension if available | |
} | |
if (redactedEmail != null) | |
{ | |
if (redactedEmail == email) | |
{ | |
// redacting rules were missed somehow, just return some sort of redacting | |
return CreateDefaultRedactEmail(email); | |
} | |
// all good, return the redacted email | |
return redactedEmail; | |
} | |
// somehow this rules did not do what is expected, so at least return something instead of the real email | |
return CreateDefaultRedactEmail(email); | |
} | |
catch (Exception ex) | |
{ | |
return CreateDefaultRedactEmail(email); | |
} | |
private string CreateDefaultRedactEmail(string email) | |
{ | |
// these are cut down versions of redacting as they are unlikely to occur | |
// no '@' was detected | |
if (email.Length == 1) | |
return "*"; // good luck in knowing if this is the users email | |
else if (email.Length == 2) | |
return email[0].ToString() + new string('*', email.Length - 1); | |
else if (email.Length >= 3) | |
// This will happen if we don't know how to handle the email | |
// eg: s@l.com", "s*****m | |
return email[0].ToString() + new string('*', email.Length - 2) + email[email.Length - 1].ToString(); | |
return "???@???"; | |
} | |
} | |
/* | |
using Microsoft.VisualStudio.TestTools.UnitTesting; | |
using Shouldly; | |
using System; | |
namespace Tests.Redactors | |
{ | |
[TestClass] | |
public class EmailRedactorTests | |
{ | |
EmailRedactor _emailRedactor = new EmailRedactor(); | |
[TestMethod] | |
[DataTestMethod] | |
[DataRow("", "")] | |
[DataRow(" ", " ")] | |
[DataRow(null, null)] | |
// expected out come when email contains '@' and '.', all following the rule... | |
// reveal the first char of the email sting, also reveal the characters left and right of the '@', and reveal the full domain extension. | |
[DataRow("some@gmail.com", "s**e@g****.com")] | |
[DataRow("s@192.168.0.1", "s@1********.1")] // https://stackoverflow.com/questions/31806538/how-to-do-masking-hiding-email-address-in-c-sharp | |
[DataRow("s@gmail.com", "s@g****.com")] | |
[DataRow("some@l.com", "s**e@l.com")] | |
[DataRow("s@l.com", "s*****m")] // after redacting executed, this pattern will reveal the email anyway, hence the `s*****m` pattern. | |
[DataRow("s@l.i", "s***i")] // same test as above, just testing the minimum number of characters | |
[DataRow("aa@b", "a**b")] // same test as above, just testing different pattern | |
[DataRow("some@.com", "s*******m")] // seems like an invalid email anyway | |
[DataRow("s@.it", "s***t")] // seems like an invalid email anyway | |
[DataRow("some@email", "s**e@e****")] | |
[DataRow("a@bb", "a@b*")] | |
// not likely email address | |
[DataRow("a", "*")] | |
[DataRow("ab", "a*")] | |
[DataRow("abc", "a*c")] | |
[DataRow("someE", "s***E")] | |
[DataRow("something@new.to.try.out", "s*******g@n*********.out")] | |
public void Redact_Emails(string emailInput, string expectedOutput) | |
{ | |
_emailRedactor.Redact(emailInput).ShouldBe(expectedOutput); | |
} | |
} | |
} | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment