How to mask a number with stars except the last 4 digits in Swift

3 Answers

0 votes
extension String {
    /// Masks all leading characters with a specified character, 
    /// keeping the last 'visibleCount' visible.
    func masked(visibleCount: Int = 4, maskChar: Character = "*") -> String {
        guard count > visibleCount else { return self }
        
        let maskLength = count - visibleCount
        let maskedPrefix = String(repeating: maskChar, count: maskLength)
        let visibleSuffix = suffix(visibleCount)
        
        return maskedPrefix + visibleSuffix
    }
}

// Examples:
let cardNumber = "1234567890123456"
let accountID = 9876543210
let shortCode = "123"

print(cardNumber.masked())                  // ************3456
print(String(accountID).masked())           // ******3210
print(shortCode.masked())                   // 123



/*
run:

************3456
******3210
123

*/

 



answered Oct 6 by avibootz
0 votes
func maskNumber(_ value: CustomStringConvertible, visibleCount: Int = 4, maskChar: Character = "*") -> String {
    let str = value.description
    guard str.count > visibleCount else { return str }
    
    let maskLength = str.count - visibleCount

    return String(repeating: maskChar, count: maskLength) + str.suffix(visibleCount)
}

print(maskNumber(1234567890123456)) // ************3456



/*
run:

************3456

*/

 



answered Oct 6 by avibootz
0 votes
extension String {
    /// Masks digits while leaving non-digit formatting intact.
    func maskedDigitsKeepFormat(visibleDigits: Int = 4, maskChar: Character = "*") -> String {
        let totalDigits = filter { $0.isNumber }.count
        guard totalDigits > visibleDigits else { return self }
        
        let digitsToMask = totalDigits - visibleDigits
        var maskedCount = 0
        
        let maskedChars = map { char -> Character in
            if char.isNumber {
                if maskedCount < digitsToMask {
                    maskedCount += 1
                    return maskChar
                }
                return char
            }
            return char // Preserve hyphens, spaces, etc.
        }
        
        return String(maskedChars)
    }
}

// Examples:
let formattedCard = "1234-5678-9012-3456"
let phone = "+1 (800) 555-0199"

print(formattedCard.maskedDigitsKeepFormat()) // ****-****-****-3456
print(phone.maskedDigitsKeepFormat())         // +* (***) ***-0199


/*
run:

****-****-****-3456
+* (***) ***-0199

*/

 



answered Oct 6 by avibootz
...