Skip to content

Commit

Permalink
Improve bin checking, shorter error correction duration (#6)
Browse files Browse the repository at this point in the history
  • Loading branch information
kingst authored Apr 5, 2019
1 parent 8a28f4c commit 71aa6f1
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 6 deletions.
2 changes: 1 addition & 1 deletion CardScan.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'CardScan'
s.version = '1.0.4037'
s.version = '1.0.4040'
s.summary = 'Scan credit cards'
s.description = <<-DESC
CardScan is a library for scanning credit cards.
Expand Down
44 changes: 41 additions & 3 deletions CardScan/Classes/CreditCardUtils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ struct CreditCardUtils {
static func luhnCheck(_ cardNumber: String) -> Bool {
if cardNumber.count == 0 {
return false
} else if cardNumber.count == 16 && !cardNumber.starts(with: "4") && !cardNumber.starts(with: "5") {
return false
} else if cardNumber.count == 15 && !cardNumber.starts(with: "3") {
} else if !isValidBin(number: cardNumber) {
return false
}

Expand All @@ -26,6 +24,46 @@ struct CreditCardUtils {
return sum % 10 == 0
}

static func isValidBin(number: String) -> Bool {
return isAmex(number: number) || isDiscover(number: number) || isVisa(number: number) || isMastercard(number: number)
}

static func isAmex(number: String) -> Bool {
guard let prefix = Int(String(number.prefix(2))) else {
return false
}

return number.count == 15 && (prefix == 34 || prefix == 37)
}

static func isDiscover(number: String) -> Bool {
guard let prefix2 = Int(String(number.prefix(2))), let prefix4 = Int(String(number.prefix(4))), let prefix6 = Int(String(number.prefix(6))) else {
return false
}

return prefix2 == 64 || prefix2 == 65 || prefix4 == 6011 ||
(prefix6 >= 622126 && prefix6 <= 622925) ||
(prefix6 >= 624000 && prefix6 <= 626999) ||
(prefix6 >= 628200 && prefix6 <= 628899)
}

static func isMastercard(number: String) -> Bool {
guard let prefix2 = Int(String(number.prefix(2))), let prefix4 = Int(String(number.prefix(4))) else {
return false
}

if number.count != 16 {
return false
}

return (prefix2 >= 51 && prefix2 <= 55) || (prefix4 >= 2221 && prefix4 <= 2720)
}

static func isVisa(number: String) -> Bool {
return number.count == 16 && number.starts(with: "4")
}


static func format(number: String) -> String {
if number.count == 16 {
return format16(number: number)
Expand Down
6 changes: 4 additions & 2 deletions CardScan/Classes/Ocr.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ public class Ocr {
public var scanStats = ScanStats()
public var expiry: Expiry?

public var errorCorrectionDuration = 1.0

public init() {}

static func configure() {
Expand Down Expand Up @@ -68,9 +70,9 @@ public class Ocr {

let numberResult = self.numbers.sorted { $0.1 > $1.1 }.map { $0.0 }.first
let expiryResult = self.expiries.sorted { $0.1 > $1.1 }.map { $0.0 }.first
let done = interval >= 1.5
let done = interval >= self.errorCorrectionDuration

if interval >= 0.75 {
if interval >= (self.errorCorrectionDuration / 2.0) {
return (numberResult, expiryResult, done)
} else {
return (numberResult, nil, done)
Expand Down

0 comments on commit 71aa6f1

Please sign in to comment.