验证信用卡号码

viv*_*iya 1 validation ios

我从用户那里获取信用卡号作为输入.我想允许16个数字,并希望在每个4个数字后格式化空格.为此,我做了以下.

-(void)cardNumberValidation:(id)sender{
    UITextField *temp=sender;

    if ([temp.text length]>19) {
        txtCard.text= [temp.text substringToIndex:[temp.text length] - 1];
    }
    if ([temp.text length]==4) {
        txtCard.text=[NSString stringWithFormat:@"%@ ",temp.text];

        }
    if ([temp.text length]==9) {
        txtCard.text=[NSString stringWithFormat:@"%@ ",temp.text];
        }
    if ([temp.text length]==14) {
        NSString *lastChar = [txtCard.text substringFromIndex:[txtCard.text length] - 1];
        txtCard.text=[NSString stringWithFormat:@"%@ ",temp.text];
    }
}
Run Code Online (Sandbox Code Playgroud)

但是现在当用户输入所有内容后删除字符然后如果它将达到15个字符,然后用户将删除另外一个字符,那么此代码将在其后添加空格,并且不允许进一步删除它.

任何人都可以给我这个或更好的方法来做这个建议.

Edu*_*ros 10

在斯威夫特

enum CardType: String {
    case Unknown, Amex, Visa, MasterCard, Diners, Discover, JCB, Elo, Hipercard, UnionPay

    static let allCards = [Amex, Visa, MasterCard, Diners, Discover, JCB, Elo, Hipercard, UnionPay]

    var regex : String {
        switch self {
        case .Amex:
           return "^3[47][0-9]{5,}$"
        case .Visa:
           return "^4[0-9]{6,}([0-9]{3})?$"
        case .MasterCard:
           return "^(5[1-5][0-9]{4}|677189)[0-9]{5,}$"
        case .Diners:
           return "^3(?:0[0-5]|[68][0-9])[0-9]{4,}$"
        case .Discover:
           return "^6(?:011|5[0-9]{2})[0-9]{3,}$"
        case .JCB:
           return "^(?:2131|1800|35[0-9]{3})[0-9]{3,}$"
        case .UnionPay:
           return "^(62|88)[0-9]{5,}$"
        case .Hipercard:
           return "^(606282|3841)[0-9]{5,}$"
        case .Elo:
           return "^((((636368)|(438935)|(504175)|(451416)|(636297))[0-9]{0,10})|((5067)|(4576)|(4011))[0-9]{0,12})$"
        default:
           return ""
        }
    }
}
extension UITextField{ 

func validateCreditCardFormat()-> (type: CardType, valid: Bool) {
        // Get only numbers from the input string
        var input = self.text!
        let numberOnly = input.stringByReplacingOccurrencesOfString("[^0-9]", withString: "", options: .RegularExpressionSearch)

    var type: CardType = .Unknown
    var formatted = ""
    var valid = false

    // detect card type
    for card in CardType.allCards {
        if (matchesRegex(card.regex, text: numberOnly)) {
            type = card
            break
        }
    }

    // check validity
    valid = luhnCheck(numberOnly)

    // format
    var formatted4 = ""
    for character in numberOnly.characters {
        if formatted4.characters.count == 4 {
            formatted += formatted4 + " "
            formatted4 = ""
        }
        formatted4.append(character)
    }

    formatted += formatted4 // the rest

    // return the tuple
    return (type, valid)
}

func matchesRegex(regex: String!, text: String!) -> Bool {
    do {
        let regex = try NSRegularExpression(pattern: regex, options: [.CaseInsensitive])
        let nsString = text as NSString
        let match = regex.firstMatchInString(text, options: [], range: NSMakeRange(0, nsString.length))
        return (match != nil)
    } catch {
        return false
    }
}

func luhnCheck(number: String) -> Bool {
    var sum = 0
    let digitStrings = number.characters.reverse().map { String($0) }

    for tuple in digitStrings.enumerate() {
        guard let digit = Int(tuple.element) else { return false }
        let odd = tuple.index % 2 == 1

        switch (odd, digit) {
        case (true, 9):
            sum += 9
        case (true, 0...8):
            sum += (digit * 2) % 9
        default:
            sum += digit
        }
    }

    return sum % 10 == 0
}
}
Run Code Online (Sandbox Code Playgroud)

请访问http://kalapun.com/posts/card-checking-in-swift/


zap*_*aph 5

不要更改用户输入的文本,它只会造成混乱。不要让用户认为:WTF。用户以他理解的方式输入号码,尽可能地尊重它。

只需清理用户输入的内容。通常只删除所有前导、训练和散布的空格字符,可能是任何非数字字符。然后确保输入的文本都是数字且长度正确。

请记住,号码的长度可以是 13 到 19 位,美国运通是 15 位。见:银行卡号

考虑代码:

if ([temp.text length]>19) {
    txtCard.text= [temp.text substringToIndex:[temp.text length] - 1];
}
Run Code Online (Sandbox Code Playgroud)

如果用户在组之间输入了额外的空格字符,最后一位数字将被删除。想出这样一个计划将避免所有可能的陷阱是非常容易的。
示例:“1234 4567 9012 3456”将被截断为“1234 4567 9012 345”。

额外,校验校验位的方法:

+ (BOOL)isValidCheckDigitForCardNumberString:(NSString *)cardNumberString {
    int checkSum = 0;
    uint8_t *cardDigitArray = (uint8_t *)[cardNumberString dataUsingEncoding:NSUTF8StringEncoding].bytes;
    int digitsCount = (int)cardNumberString.length;
    BOOL odd = cardNumberString.length % 2;

    for (int digitIndex=0; digitIndex<digitsCount; digitIndex++) {
        uint8_t cardDigit = cardDigitArray[digitIndex] - '0';
        if (digitIndex % 2 == odd) {
            cardDigit = cardDigit * 2;
            cardDigit = cardDigit / 10 + cardDigit % 10;
        }
        checkSum += cardDigit;
    }

    return (checkSum % 10 == 0);
}

BOOL checkDigitValid = [TestClass isValidCheckDigitForCardNumberString:@"371238839571772"];
NSLog(@"check digit valid: %@", checkDigitMatch ? @"yes" : @"no");
Run Code Online (Sandbox Code Playgroud)

输出:

校验位有效:是