0

I want to mask the email id as follows :

Input                   |   Output
qwerty@gmail.com        : qw**ty@gmail.com
helloworld@gmail.com    : he******ld@gmail.com
stackoverflow@gmail.com : st*********ow@gmail.com
abcde@gmail.com         : ab*de@gmail.com
abcd@gmail.com          : a**d@gmail.com
abc@gmail.com           : a*c@gmail.com
ab@gmail.com            : a*@gmail.com
  1. Max 2 characters at both the extremes if available, minimum 1 character at each end are to be displayed or just mask the last character.

  2. The string has to be atleast 2 characters in length (ab@gmail.com).

I referred some of the solutions provided, but was not able to achieve the second and third scenario using those. Is there a possibility to find a fix ? I'm not well versed with regex, so I'm not sure which way to go ahead.

references : masking of email address in java

How to i mask all string characters except for the last 4 characters in Java using parameters?

vi90
  • 73
  • 8
  • [Here's](https://ideone.com/khzI3K) an IDEOne example showing one way to do it. Not saying it's the best/most efficient, just first thing that came to mind. Not putting as an answer, as I didn't do it with regex at all :/. – BeUndead Sep 21 '20 at 15:43
  • Could you please put some more, longer examples to refine the requirement of "centre"? (That is, email id of length 7,8,9,10) Also, do you require a regex or will another solution work? – Michael Easter Sep 21 '20 at 15:51
  • @MichaelEaster: I have added some more examples, maybe that would help ? – vi90 Sep 21 '20 at 15:55
  • With the newly added examples, you can ignore my solution above. This assumed you wanted to evenly split '\*'s and non-'\*' components for any length. – BeUndead Sep 21 '20 at 15:55
  • Just curious what should happen with email address a@example.com – Aleks G Sep 21 '20 at 16:00
  • How should it be done for `abcd@gmail.com` and `abcde@gmail.com`? – Arvind Kumar Avinash Sep 21 '20 at 16:03
  • Have made some edits, to clarify further – vi90 Sep 21 '20 at 16:20

3 Answers3

1

Interesting reads regarding what can, and what can not be in an E-Mail Address would be this SO Post and this SO Post especially if you want to utilize Regular Expressions.

Here is another method to accomplish the task at hand:

public static String maskEMailAddress(String emailAddy) {
    String id = emailAddy.substring(0, emailAddy.lastIndexOf("@"));
    String domain = emailAddy.substring(emailAddy.lastIndexOf("@"));
    if (id.length() <= 1) { 
        return emailAddy;
    }
    switch (id.length()) {
        case 2:
            id = id.substring(0,1) + "*";
            break;
        case 3:
            id = id.substring(0,1) + "*" + id.substring(2);
            break;
        case 4:
            id = id.substring(0,1) + "**" + id.substring(3);
            break;
        default:
            String masks = String.join("", java.util.Collections.nCopies(id.length() - 4, "*"));
            id = id.substring(0,2) + masks + id.substring(id.length() - 2);
            break;
    }

    String address = id + domain;
    return address;
}
DevilsHnd - 退職した
  • 8,739
  • 2
  • 19
  • 22
0

Working code is located here

Consider a method that replaces a regex within an input string (credit to this answer):

String replace(String regex, String replacement, String input) {
    String result = "N/A";

    Matcher m = Pattern.compile(regex).matcher(input);
    if (m.find()) {
        int groupToReplace = 1;
        result = new StringBuilder(input).replace(m.start(groupToReplace),
                                                  m.end(groupToReplace),
                                                  replacement).toString();
    } else {
        throw new IllegalStateException("internal error");
    }

    return result;
}

then the various cases can be isolated into client code. Here, we assume that the "email id" has been stripped from the email address. (e.g. qwerty is input and not qwerty@gmail.com). Code snippet:

// TODO: the regex strings can be compiled into proper Pattern objects
if (numChars == 2) {
    regex = ".(.)";
    replacement = ASTERISK;
} else if (numChars == 3) {
    regex = ".(.).";
    replacement = ASTERISK;
} else if (numChars == 4) {
    regex = ".(..).";
    replacement = ASTERISK + ASTERISK;
} else {
    regex = "..(.*)..";
    int numAsterisks = numChars - 4;

    // requires JDK 11+
    replacement = ASTERISK.repeat(numAsterisks);
}

String result = replace(regex, replacement, input);

Above, note that String.repeat was introduced in JDK 11.

This is neither efficient nor elegant but is somewhat readable (esp. if unit-tested thoroughly). It has a simplistic treatment of what constitutes an email address.

Another solution, which doesn't use regular expressions, is included here.

Michael Easter
  • 23,733
  • 7
  • 76
  • 107
0

Alternative regex:

"(?:(\\w{2})(\\w+)(\\w{2}@.*)|(\\w)(\\w{1,2})(\\w@.*)|(\\w)(\\w)(@.*))"

Regex in context:

public static void main(String[] args) {
    String str = "qwerty@gmail.com\n"
            + "helloworld@gmail.com\n"
            + "stackoverflow@gmail.com\n"
            + "abcde@gmail.com\n"
            + "abcd@gmail.com\n"
            + "abc@gmail.com\n"
            + "ab@gmail.com";

    // 9 matcher group in total
    Pattern pattern = Pattern.compile("(?:(\\w{2})(\\w+)(\\w{2}@.*)|(\\w)(\\w{1,2})(\\w@.*)|(\\w)(\\w)(@.*))");
    List<Integer> groupIndex = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
    for (String email : str.split("\n")) {
        Matcher matcher = pattern.matcher(email);
        if(matcher.find()) {
            List<Integer> activeGroupIndex = groupIndex.stream()
                    .filter(i -> matcher.group(i) != null)
                    .collect(Collectors.toList());
            String prefix = matcher.group(activeGroupIndex.get(0));
            String middle = matcher.group(activeGroupIndex.get(1));
            String suffix = matcher.group(activeGroupIndex.get(2));
            System.out.printf("%s%s%s%n", prefix, "*".repeat(middle.length()), suffix);
        }
    }
}

Output:

qw**ty@gmail.com
he******ld@gmail.com
st*********ow@gmail.com
ab*de@gmail.com
a**d@gmail.com
a*c@gmail.com
a*@gmail.com

Note: "String repeat​(int count)" only works from Java 11 and up.

DigitShifter
  • 801
  • 5
  • 12