I have a card number as a string, for example:
string ClsCommon.str_CardNumbe r = "3456123434561234";
The length of this card number can vary from 16 to 19 digits, depending on the requirement.
My requirement is that I have to show the first six digits and the last 4 digits of a card number and mask the other characters in between with the character 'X'.
I have tried using subString and implemented it separately for 16,17,18,19 digits..
I split string(ClsCommon.str_CardNumber) to 5 strings (str_cardNum1, str_cardNum2, str_cardNum3, str_cardNum4, str_cardNum5 - 4 digits for each string..remaining digits for 5th string)
All the strings are placed in ClsCommon file. Based on that I implemented the below, which works perfectly:
if (ClsCommon.str_CardNumber.Length == 16) {
txtmskcrdnum.Text = string.Concat(ClsCommon.str_cardNum1, " ", ClsCommon.str_cardNum2.Substring(0, 2), "XX", " ", "XXXX", " ", ClsCommon.str_cardNum4);
}
if (ClsCommon.str_CardNumber.Length == 17) {
txtmskcrdnum.Text = string.Concat(ClsCommon.str_cardNum1, " ", ClsCommon.str_cardNum2.Substring(0, 2), "XX", " ", "XXXX", " ", "X", ClsCommon.str_cardNum4.Substring(1, 3), " ", ClsCommon.str_cardNum5);
}
if (ClsCommon.str_CardNumber.Length == 18) {
txtmskcrdnum.Text = string.Concat(ClsCommon.str_cardNum1, " ", ClsCommon.str_cardNum2.Substring(0, 2), "XX", " ", "XXXX", " ", "XX", ClsCommon.str_cardNum4.Substring(2, 2), " ", ClsCommon.str_cardNum5);
}
if (ClsCommon.str_CardNumber.Length == 19) {
txtmskcrdnum.Text = string.Concat(ClsCommon.str_cardNum1, " ", ClsCommon.str_cardNum2.Substring(0, 2), "XX", " ", "XXXX", " ", "XXX", ClsCommon.str_cardNum4.Substring(3, 1), " ", ClsCommon.str_cardNum5);
}
txtmskcrdnum.Text = ClsCommon.str_CardNumber.PadLeft(ClsCommon.str_CardNumber.Length, 'X').Substring(ClsCommon.str_CardNumber.Length - 4);
For multiple lengths, the above approach is not useful.
I want a single approach which displays the first 6 and last 4 digits and masks other digits with X. The final string should have a space between every 4 digits.
Many of the given solutions parse the input multiple times. Below I present a solution that parses the input only once. But I have no experience in C#, so the function is written in Scheme.
The function is divided into two:
(1) visit-first-6 parses the first six characters and concatenates them to the rest of the computation. When visit-first-6 has parsed the first six characters, it calls visit-rest.
(2) visit-rest exploits the fact that we can delay some computation until we have gained more knowledge. In this case, we wait to determine whether the element in the list should be shown until we know how many characters are left.
Running mask in the Petite Chez Scheme interpreter
NB. I saw this as a funny exercise and I figured I might as well share it. Yannick Meeus has already provided an easily understandable solution. So, this only serves for the interested.
How about replacing a specific matched group using Regex :
I'm sure there is a cleaner way to do this:
Try this one. Simple and straight forward.
Possible implementation (acccepts varios formats e.g. numbers can be divided into groups etc.):
this implementation just masks the digits and preserve the format.
This will work with any card number length: