我从用户那里获取信用卡号作为输入.我想允许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/
不要更改用户输入的文本,它只会造成混乱。不要让用户认为: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)
输出:
校验位有效:是
| 归档时间: |
|
| 查看次数: |
11371 次 |
| 最近记录: |