Created
December 30, 2017 12:53
-
-
Save dedeexe/5a4a41c6e9f41bbfc82554c5de9622b4 to your computer and use it in GitHub Desktop.
Validate CPF and Create CPF digits
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// CPF.swift | |
// | |
// Created by dede.exe on 30/12/17. | |
// Copyright © 2017 dede.exe. All rights reserved. | |
// | |
import Foundation | |
/// | |
/// Create an CPF Object | |
/// | |
public struct CPF { | |
private (set) public var number : String = "" | |
/// Create a new CPF entity with number | |
public init(number:String) { | |
self.number = number | |
} | |
/// Get CPF digits verification | |
var digits : String { | |
return calculateCPFDigits() ?? "" | |
} | |
/// Check if it is a valida CPF | |
var isValid : Bool { | |
if number.count != 11 { return false } | |
if isAnException { return false } | |
return self.number.hasSuffix(digits) | |
} | |
// MARK: - Helpers | |
private var isAnException : Bool { | |
for n in 0...9 { | |
let number = String(repeating: String(n), count: 11) | |
if self.number == number { return true } | |
} | |
return false | |
} | |
private func calculateCPFDigits() -> String? { | |
var result : String = "" | |
guard canCalculate() else { return nil } | |
let startIndex = self.number.startIndex | |
let endIndex = self.number.index(startIndex, offsetBy: 9) | |
let number = String(self.number[startIndex..<endIndex]) | |
result = calculateDigit(for: number) | |
result = result + calculateDigit(for: number + result) | |
return result | |
} | |
private func calculateDigit(for number:String) -> String { | |
let firstDigitSize = 9 | |
let secondDigitSize = 10 | |
let numberSize = number.count | |
var values : [Int] = [] | |
if numberSize < firstDigitSize || numberSize > secondDigitSize { | |
return "" | |
} | |
let factor = (numberSize == firstDigitSize) ? firstDigitSize + 1 : secondDigitSize + 1 | |
for (index,char) in number.enumerated() { | |
let v = (Int(String(char)) ?? 0) * (factor - index) | |
values.append(v) | |
} | |
var result = values.reduce(0) { $0 + $1 } | |
result = result * 10 % 11 | |
result = (result < 10) ? result : 0 | |
return String(result) | |
} | |
private func canCalculate() -> Bool { | |
return number.count >= 9 | |
} | |
} | |
//Usage | |
let cpf1 = CPF(number: "123123123").digits // "87" | |
let cpf2 = CPF(number: "12312312387").isValid // true | |
let cpf3 = CPF(number: "12312312387").isValid // true | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment