check iban and bic in swift

Here's an example code which validates IBAN and BIC using Swift 5:

main.swift
enum ValidationResult {
    case valid
    case invalid(String)
}

class IBAN {
    static func validate(_ iban: String) -> ValidationResult {
        let cleanedIBAN = iban.replacingOccurrences(of: "\\s", with: "", options: .regularExpression)
        guard cleanedIBAN.count <= 34 else { return .invalid("IBAN is too long") }
        guard cleanedIBAN.count >= 15 else { return .invalid("IBAN is too short") }
        
        let countryCode = String(cleanedIBAN.prefix(2))
        guard countryCode.rangeOfCharacter(from: CharacterSet.letters.inverted) == nil else { return .invalid("Invalid Country Code") }
        
        let checkDigits = String(cleanedIBAN.dropFirst(2)).replacingOccurrences(of: "\\s", with: "", options: .regularExpression) + countryCode
        let digits = checkDigits.utf8.map { $0 }
        
        let computedCheckDigit = digits.reduce(into: 0) { result, digit in
            let num: Int
            switch digit {
            case let x where x >= 48 && x <= 57:
                num = digit - 48
            case let x where x >= 65 && x <= 90:
                num = digit - 55
            default:
                num = 0
            }
            result = (result * 10 + num) % 97
        }
        guard computedCheckDigit == 1 else { return .invalid("Invalid Check Digit") }
        return .valid
    }
}

class BIC {
    static func validate(_ bic: String) -> ValidationResult {
        let cleanedBIC = bic.replacingOccurrences(of: "\\s", with: "", options: .regularExpression)
        guard cleanedBIC.count <= 11 else { return .invalid("BIC is too long") }
        
        let range = NSRange(location: 0, length: cleanedBIC.utf16.count)
        let regex = try! NSRegularExpression(pattern: "^[A-z]{4}[A-z]{2}[A-z2-9]{2}([A-z0-9]{3})?$")
        let matches = regex.matches(in: cleanedBIC, options: [], range: range)
        if matches.count > 0 {
            return .valid
        } else {
            return .invalid("Invalid BIC")
        }
    }
}

let ibanValidation = IBAN.validate("GB82 WEST 1234 5698 7654 32")
print("IBAN Validation: ", ibanValidation)

let bicValidation = BIC.validate("ABNAGB2LXXX")
print("BIC Validation: ", bicValidation)
2199 chars
56 lines

The code above is creating two classes: IBAN and BIC. Each class has a static function validate that accepts an IBAN or BIC number as a string parameter, and returns an enumerated ValidationResult which either .valid or .invalid with corresponding error message.

The validation logic for IBAN follows the rules as stated in this document: https://en.wikipedia.org/wiki/International_Bank_Account_Number#Validating_the_IBAN.

The validation logic for BIC follows the official SWIFT documentation: https://www2.swift.com/uhbonline/books/public/en_uk/l2/l2_standard_format.htm.

related categories

gistlibby LogSnag