How to mask a credit card number with asterisks in Python

Mask a credit card number with asterisks in Python

We can hide the last four digits of a credit card number with an asterisk in Python.

Let’s assume that we have a credit card number in a 16-digit standard format, and we expect the output to be as follows: 

  • Input: 60115564485789458

  Output: ************9458

  • Input: 5425 2334 3010 9903

  Output: **** **** **** 9903

  • Input: 4263 9826 4026 9299

  Output: **** **** **** 9299

Solution

To define this program, we'll provide three inputs as the function's arguments: the credit card number as a string (cc_string), four digits in the credit card string (digits_to_keep=4), and an asterisk to hide the character of each number in the credit card string (mask_char='*'). The number of digits to keep and the character to hide is known as default arguments, which are assigned when the function is defined.

def mask_cc_number(cc_string, digits_to_keep=4, mask_char='*'):
  • The first task is to create a variable, cc_string_total to hold the total of the characters in the string. We'll need two functions (map and sum) to complete this task. 
cc_string_total = sum(map(str.isdigit, cc_string))
  1. First step, we need to map or loop over the string to check if each character is a digit. In Python, a string can be iterated over like a list. For this step, we'll use the map function, which takes a str object and calls isdigit on each str object in the cc_string and the iterable (or an array of iterables) which is the cc_string
  2. Second step, if the digit is a number, then we'll sum the total number of characters in the credit card string. If the cc_string has a space in it, the isdigit function in the previous step will ignore it. 
  • For the second task, we check if the number of digits to keep is greater than or equal to the sum of the credit card string.
 if digits_to_keep >= cc_string_total:

If this is the case, then provide an error message that the credit card string provided is not long enough. When the credit card string is 4 characters, all 4 characters will be masked by the asterisk. Or if the credit card string is less than 4 characters, the original credit card string will be returned unchanged. If either of these statements are true, the program will provide the error message. 

print("Not enough numbers. Add 10 or more numbers to the credit card number.")
  • For the third task, create another variable that will hold the difference between the credit card string total and the number of digits to keep. 
digits_to_mask = cc_string_total - digits_to_keep
  • Lastly, create a variable that will return the cc_string replaced with the asterisk.
masked_cc_string = re.sub('\d', mask_char, cc_string, digits_to_mask)

Here, we'll use the sub() function from the re module (re is regular expression) that takes in five parameters: the pattern of digits to find in the string, the replacement character, the string or function, the count and the flag, which can ignore the letter case. Make sure to add import re as the first line in the program to import the re module.

return masked_cc_string
  • After the program, call mask_cc_number() with a cc_string. To show the results with the masked characters, enclose the mask_cc_number() function within a print statement.
print(mask_cc_number("4289 9826 4026 9299"))

Example

import re
def mask_cc_number(cc_string, digits_to_keep=4, mask_char='*'):
cc_string_total = sum(map(str.isdigit, cc_string))
if digits_to_keep >= cc_string_total:
print("Not enough numbers. Add 10 or more numbers to the credit card number.")
digits_to_mask = cc_string_total - digits_to_keep
masked_cc_string = re.sub('\d', mask_char, cc_string, digits_to_mask)
return masked_cc_string
print(mask_cc_number("4259 9826 4026 9299"))
print(mask_cc_number("4259 982& 4026 9299"))
print(mask_cc_number("4259 9826 40p6 9299"))

Explanation

  • Line 1: Import the re module.
  • Line 4: Define cc_string_total to hold the total of the characters in the string.
  • Line 7–8: Check if digits_to_keep >= cc_string_total is true and provide an error message.
  • Line 10: Define digits_to_mask as the difference between cc_string_total and digits_to_keep.
  • Line 11: Define masked_cc_string as the value of the regex sub() function call.
  • Line 13: Return the value of masked_cc_string.

Note: if the character is not a digit, such as a letter or a symbol, the character will not be masked by an asterisk. However, the character will be counted towards the total number of characters in the credit card string.