Main| Programming| Travel| Life| Audio Books| Movies| About Me
Obscuring Credit Card Numbers
2008-07-04
One of the requirements for PCI compliance, is to not store credit card numbers. That applies also to log files. You need logs to debug, but usually you do not need the whole number. The common practice is to show only the last 4 digits of the number. You can obscure the number at the source or if it is not possible you can obsure it before logging. How do you know that a number is a credit card number? Check out this wikipedia article:
http://en.wikipedia.org/wiki/Credit_card_number
As you can see it may not be very easy. The simplified rule is that card numbers have from 13 to 19 digits, most often 16. You can use this rule, to obscure all credit card numbers (and a bit more). Here is the .NET C# code:
using System.Text.RegularExpressions; public static class Utils { const string crediCardNumberSearchPattern = @"(\d{9,15})(\d{4})"; const string crediCardNumberReplacementString = "XXXX-XXXX-XXXX-$2"; ///<summary> /// Obscures credit card numbers by replacing any 13 to 19 digit number /// with "XXXX-XXXX-XXXX-" and the last 4 digits of the number. ///</summary> public static string ObscureCreditCardNumbers(string stringToObscure) { string obscuredString = null; if (stringToObscure != null) { obscuredString = Regex.Replace(stringToObscure, crediCardNumberSearchPattern, crediCardNumberReplacementString); } return obscuredString; } }
Your unit test may look like this:
// 12 digit number, 13 digit card number, 19 digit number, 20 digit number string testString = @"123456789012,1234567890123,1234567890123456789,12345678901234567890"; string expectedResult = @"123456789012,XXXX-XXXX-XXXX-0123,XXXX-XXXX-XXXX-6789,12345678901234567890"; string actualString = Utils.ObscureCreditCardNumbers(testString); bool ignoreCase = true; Assert.AreEqual(expectedResult, actualString, ignoreCase); // test for null Assert.IsNull(Utils.ObscureCreditCardNumbers(null));