Skip to content

Instantly share code, notes, and snippets.

@igorcferreira
Last active March 6, 2017 14:12
Show Gist options
  • Save igorcferreira/6779d56da9878f991bb42d88a58757ac to your computer and use it in GitHub Desktop.
Save igorcferreira/6779d56da9878f991bb42d88a58757ac to your computer and use it in GitHub Desktop.
Basic implementation to apply different regexes over a card number String and find the card type
import Foundation
enum CardTypeError:Error {
case TypeNotFound
}
enum CardType:CustomStringConvertible {
case visa
case mastercard
case amex
case diners
case elo
case jcb
fileprivate var regex:String {
switch self {
case .visa:
return "^4[0-9]{6,}$"
case .mastercard:
return "^5[0-9]{6,}$"
case .amex:
return "^3[47][0-9]{13}$"
case .diners:
return "^3(?:0[0-5]|[68][0-9])[0-9]{11}$"
case .elo:
return "^[456](?:011|38935|51416|576|04175|067|06699|36368|36297)\\d{10}(?:\\d{2})?$"
case .jcb:
return "^(?:2131|1800|35\\d{3})\\d{11}$"
}
}
var description: String {
switch self {
case .visa:
return "Visa"
case .mastercard:
return "Mastercard"
case .amex:
return "American Express"
case .diners:
return "Diners"
case .elo:
return "Elo"
case .jcb:
return "JCB"
}
}
init(cardNumber:String) throws {
self = try [CardType.visa, .mastercard, .amex, .diners, .elo, .jcb].type(of: cardNumber)
}
func includes(_ cardNumber:String) -> Bool {
let predicate = NSPredicate(format: "SELF MATCHES [c] %@", regex)
let result = predicate.evaluate(with: cardNumber)
return result
}
}
extension Sequence where Iterator.Element == CardType {
func type(of input:String) throws -> Iterator.Element {
guard let cardType = self.lazy.first(where: { $0.includes(input) }) else {
throw CardTypeError.TypeNotFound
}
return cardType
}
}
let cardNumber = "4172368939385121"
let supportedTypes = [CardType.visa, .mastercard, .amex, .diners, .elo, .jcb]
if let cardType = supportedTypes.lazy.first(where: { $0.includes(cardNumber) }) {
print("Print card type: \(cardType)") //Prints Visa
}
//: Or Even
if let cardType = try? CardType(cardNumber: cardNumber) {
print("Print card type: \(cardType)") //Prints Visa
}
@fpg1503
Copy link

fpg1503 commented Mar 6, 2017

I also added Hipercard ("^(606282\\d{10}(\\d{3})?)|(3841\\d{15})$").

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment