5

i will like to know how do i mask any number of string characters except the last 4 strings. I want to masked all strings using "X"

For example

Number:"S1234567B"

Result

Number :"XXXXX567B

Thank you guys

BinQuan
  • 67
  • 2
  • 2
  • 6

4 Answers4

15

Solution 1

You can do it with a regular expression.
This is the shortest solution.

static String mask(String input) {
    return input.replaceAll(".(?=.{4})", "X");
}

The regex matches any single character (.) that is followed (zero-width positive lookahead) by at least 4 characters ((?=.{4})). Replace each such single character with an X.


Solution 2

You can do it by getting a char[]1, updating it, and building a new string.
This is the fastest solution, and uses the least amount of memory.

static String mask(String input) {
    if (input.length() <= 4)
        return input; // Nothing to mask
    char[] buf = input.toCharArray();
    Arrays.fill(buf, 0, buf.length - 4, 'X');
    return new String(buf);
}

1) Better than using a StringBuilder.


Solution 3

You can do it using the repeat​(int count) method that was added to String in Java 11.
This is likely the easiest solution to understand.

static String mask(String input) {
    int maskLen = input.length() - 4;
    if (maskLen <= 0)
        return input; // Nothing to mask
    return "X".repeat(maskLen) + input.substring(maskLen);
}
Andreas
  • 147,606
  • 10
  • 133
  • 220
0

You can use a StringBuilder.

StringBuilder sb = new StringBuilder("S1234567B");
for (int i = 0 ; i < sb.length() - 4 ; i++) { // note the upper limit of the for loop
    // sets every character to X until the fourth to last character
    sb.setCharAt(i, 'X');
}
String result = sb.toString();
Sweeper
  • 176,635
  • 17
  • 154
  • 256
0

You can do it with the help of StringBuilder in java as follows,

String value = "S1234567B";
String formattedString = new StringBuilder(value)
    .replace(0, value.length() - 4, new String(new char[value.length() - 4]).replace("\0", "x")).toString();
System.out.println(formattedString);
823
  • 53
  • 6
  • `value = "7B"` causes `NegativeArraySizeException: -2` --- This is also the most convoluted solution presented so far. – Andreas Oct 13 '19 at 08:52
  • *"I assume the values lengths are more than 4"* You know what they say about assumptions. Besides, [defensive programming](https://en.wikipedia.org/wiki/Defensive_programming) practices to handle unexpected cases too, so unless you explicitly want it to the fail for inputs less than 4 in length, you should handle it. – Andreas Oct 13 '19 at 09:30
  • *"whats the complexity of this solution?"* Big-O complexity is _O(n)_, same as all the other solutions, but why do you ask? I said *convoluted*, as in more difficult to follow the logic. I didn't say *complex*. And even though they are all _O(n)_ still doesn't mean they all perform the same, so again I don't understand why you ask about *complexity*. – Andreas Oct 13 '19 at 09:43
0

My class to mask simple String

class MaskFormatter(private val pattern: String, private val splitter: Char? = null) {

    fun format(text: String): String {
        val patternArr = pattern.toCharArray()
        val textArr = text.toCharArray()
        var textI = 0
        for (patternI in patternArr.indices) {
            if (patternArr[patternI] == splitter) {
                continue
            }
            if (patternArr[patternI] == 'A' && textI < textArr.size) {
                patternArr[patternI] = textArr[textI]
            }
            textI++
        }
        return String(patternArr)
    }
}

Example use

MaskFormatter("XXXXXAAAA").format("S1234567B") // XXXXX567B
MaskFormatter("XX.XXX.AAAA", '.').format("S1234567B") // XX.XXX.567B
MaskFormatter("**.***.AAAA", '.').format("S1234567B") // **.***.567B
MaskFormatter("AA-AAA-AAAA",'-').format("123456789") // 12-345-6789
Linh
  • 51,033
  • 19
  • 228
  • 256