{x}
blog image

Masking Personal Information

You are given a personal information string s, representing either an email address or a phone number. Return the masked personal information using the below rules.

Email address:

An email address is:

  • A name consisting of uppercase and lowercase English letters, followed by
  • The '@' symbol, followed by
  • The domain consisting of uppercase and lowercase English letters with a dot '.' somewhere in the middle (not the first or last character).

To mask an email:

  • The uppercase letters in the name and domain must be converted to lowercase letters.
  • The middle letters of the name (i.e., all but the first and last letters) must be replaced by 5 asterisks "*****".

Phone number:

A phone number is formatted as follows:

  • The phone number contains 10-13 digits.
  • The last 10 digits make up the local number.
  • The remaining 0-3 digits, in the beginning, make up the country code.
  • Separation characters from the set {'+', '-', '(', ')', ' '} separate the above digits in some way.

To mask a phone number:

  • Remove all separation characters.
  • The masked phone number should have the form:
    • "***-***-XXXX" if the country code has 0 digits.
    • "+*-***-***-XXXX" if the country code has 1 digit.
    • "+**-***-***-XXXX" if the country code has 2 digits.
    • "+***-***-***-XXXX" if the country code has 3 digits.
  • "XXXX" is the last 4 digits of the local number.

 

Example 1:

Input: s = "LeetCode@LeetCode.com"
Output: "l*****e@leetcode.com"
Explanation: s is an email address.
The name and domain are converted to lowercase, and the middle of the name is replaced by 5 asterisks.

Example 2:

Input: s = "AB@qq.com"
Output: "a*****b@qq.com"
Explanation: s is an email address.
The name and domain are converted to lowercase, and the middle of the name is replaced by 5 asterisks.
Note that even though "ab" is 2 characters, it still must have 5 asterisks in the middle.

Example 3:

Input: s = "1(234)567-890"
Output: "***-***-7890"
Explanation: s is a phone number.
There are 10 digits, so the local number is 10 digits and the country code is 0 digits.
Thus, the resulting masked number is "***-***-7890".

 

Constraints:

  • s is either a valid email or a phone number.
  • If s is an email:
    • 8 <= s.length <= 40
    • s consists of uppercase and lowercase English letters and exactly one '@' symbol and '.' symbol.
  • If s is a phone number:
    • 10 <= s.length <= 20
    • s consists of digits, spaces, and the symbols '(', ')', '-', and '+'.

Solution Explanation: Masking Personal Information

This problem involves masking personal information, specifically email addresses and phone numbers, according to specific rules. The solution efficiently determines the type of information (email or phone number) and applies the appropriate masking technique.

Approach

The core idea is to first identify whether the input string s represents an email address or a phone number. This is determined by checking if the string contains the "@" symbol. If it does, it's treated as an email; otherwise, it's considered a phone number.

Email Masking:

  1. Lowercase Conversion: The entire email is converted to lowercase.
  2. Name Masking: The name part (before the "@") is masked by replacing all characters except the first and last with asterisks ("*****").
  3. Return Masked Email: The masked name is combined with the domain part (after the "@") to construct the masked email string.

Phone Number Masking:

  1. Digit Extraction: All non-digit characters are removed from the phone number string.
  2. Country Code Determination: The length of the resulting digit string determines the country code length (number of digits before the last 10).
  3. Masking Format: Based on the country code length, a specific masking format is applied. The last four digits remain unchanged ("XXXX"), while the preceding digits are replaced with asterisks and hyphens.
  4. Return Masked Number: The masked phone number string is returned.

Time and Space Complexity

Time Complexity: O(n), where n is the length of the input string s. This is because the algorithms iterate through the string a constant number of times to perform operations like lowercase conversion, digit extraction, and masking. The operations involved have linear time complexity.

Space Complexity: O(n) in the worst case. This is because we might create intermediate strings during the masking process (e.g., to store the lowercase version of the email or the extracted digits from the phone number), and the size of these intermediate strings is proportional to the length of the input string.

Code Implementation (Python)

The Python code efficiently implements the above approach:

class Solution:
    def maskPII(self, s: str) -> str:
        if "@" in s:  # Email
            s = s.lower()
            at_index = s.index("@")
            name = s[:at_index]
            domain = s[at_index:]
            masked_name = name[0] + "*" * (len(name) - 2) + name[-1] if len(name) > 2 else name
            return masked_name + domain
        else:  # Phone Number
            digits = "".join(c for c in s if c.isdigit())
            country_code_len = len(digits) - 10
            local_number = digits[-4:]
            masked_number = "+" + "*" * country_code_len + "-" + "***-***-" + local_number if country_code_len > 0 else "***-***-" + local_number
            return masked_number
 

The code is concise and readable, clearly demonstrating the steps involved in identifying the information type and applying the respective masking rules. Other languages (Java, C++, Go, TypeScript) provide similar implementations following the same algorithmic approach. The key is to efficiently handle both email and phone number masking within a single function.