Code for credit card number anonymization

This is purely an exercise and I am not actually working with credit card numbers, but I would like some help with this section of my JavaScript class. Everything up until the spacer binder is part of the curriculum. I decided I wanted to make this look a little more complete and add a space after every four digits. I found match(/.{1,4}/g); in a search for this very functionality (here) and tried to apply it to my code without actually understanding how it works. Is this the most straightforward solution? If it is how have I implemented it incorrectly and can you break it down for me?

const maskCreditCard = function (number) {
  const str = number + '';
  const last = str.slice(-4);
  return last.padStart(str.length, '*');
  const spacer = last.match(/.{1,4}/g);
  return spacer.join(' ');
};

console.log(maskCreditCard(4916490201037007));

Thank you for taking the time!

Hi,

There are a couple of things wrong with the code. The most obvious is that you can only have one return statement per function. That means the final two lines of the maskCreditCard function are never reached.

I decided I wanted to make this look a little more complete and add a space after every four digits.

Is a credit card number always going to be 16 characters?

If so, you could do it like this:

const maskCreditCard = function (number) {
  const str = String(number);
  const last = str.slice(-4);
  return '**** **** **** ' + last;
};

console.log(maskCreditCard(4916490201037007));

// **** **** **** 7007

If not, how should the spaces be inserted if the number of digits is not divisible by 4?

1 Like

Also, if you feel like it is cheating to hard code the return value in the example above, you could also do it like this:

const maskCreditCard = function (number) {
  const str = String(number);
  const last = str.slice(-4);
  const masked = last.padStart(str.length, '*')
  const chunks = masked.match(/.{1,4}/g);
  return chunks.join(' ');
};

console.log(maskCreditCard(4916490201037007));

// **** **** **** 7007

Which achieves the same result.
Let me know which makes more sense to you and I will be happy to explain what is going on.

Is a credit card number always going to be 16 characters?

According to Experian

Credit cards that are part of the Visa, Mastercard and Discover payment networks have 16 digits, while those that are part of the American Express payment network have just 15

My solution was similar to James’

const maskCreditCard = function (number) {
  const cardNumber = String(number)
  const length = cardNumber.length

  if (length < 15 || length > 16) {
    throw 'Invalid Number of Digits'
  }

  const [input, lastDigits] = cardNumber.match(/\d{12}(\d+)/)

  return `**** **** **** ${lastDigits}`
}

Breakdown of /\d{12}(\d+)/

\d{12} match 12 digits

(\d+) matches 1 or more digits. The parentheses capture this match

1 Like

That’s a nice way to deal with it.

1 Like