CPF and CNPJ validation

Asked

Viewed 4,772 times

6

I’ve been doing research on Swift and I haven’t seen examples that contemplate the validation of both CPF and CNPJ. So any of your colleagues have a function that can validate them?

  • If you do not want to do this manually, I recommend this lib: https://github.com/fpg1503/CPF-CNPJ-Validator

  • While this link may answer the question, it is best to include the essential parts of the answer here and provide the link for reference. Replies per link only can be invalidated if the page with the link is changed. - Of Revision

2 answers

25


CPF validation

To validate the first digit of the Voce CPF you need to multiply each digit (from 1º to 9º) starting with 10 and gradually decreasing to 2 and accumulating the total of the multiplications. Then take 11 and subtract the rest of the accumulated divided by 11. If the result is greater than 9 the first check digit is 0 otherwise it is the result itself.

For the second digit verifier the method is practically the same only it is used from the 1st to the 10th digit and the multiplication starts at 11 instead of 10:


Swift 5.2 or later

extension Collection where Element == Int {
    var digitoCPF: Int {
        var number = count + 2
        let digit = 11 - reduce(into: 0) {
            number -= 1
            $0 += $1 * number
        } % 11
        return digit > 9 ? 0 : digit
    }
}

extension StringProtocol {
    var isValidCPF: Bool {
        let numbers = compactMap(\.wholeNumberValue)
        guard numbers.count == 11 && Set(numbers).count != 1 else { return false }
        return numbers.prefix(9).digitoCPF == numbers[9] &&
               numbers.prefix(10).digitoCPF == numbers[10]
    }
}

CNPJ validation

The validation of the CNPJ verification digit is very similar to that of the CPF. To validate the first digit of the CNPJ Voce you need to multiply each digit in the reverse order (from 12º to 1º) starting with 2 and increasing gradually until 9 and after 2 until 5 and accumulate the total of the multiplications. Then take 11 and subtract the rest of the accumulated divided by 11. If the result is greater than 9 the checker digit is 0 otherwise it is equal to the result itself.

For the second digit verifier the method is practically the same only it is used from the 13th to the 1st digit and the multiplication ends in 6 instead of 5:

extension Collection where Element == Int {
    var digitoCNPJ: Int {
        var number = 1
        let digit = 11 - reversed().reduce(into: 0) {
            number += 1
            $0 += $1 * number
            if number == 9 { number = 1 }
        } % 11
        return digit > 9 ? 0 : digit
    }
}

extension StringProtocol {
    var isValidCNPJ: Bool {
        let numbers = compactMap(\.wholeNumberValue)
        guard numbers.count == 14 && Set(numbers).count != 1 else { return false }
        return numbers.prefix(12).digitoCNPJ == numbers[12] &&
               numbers.prefix(13).digitoCNPJ == numbers[13]
    }
}

Playground

let cpf1 = "957.621.155-77"
let cpf2 = "746.043.382-99"
let cpf3 = "111.111.111-11"

cpf1.isValidCPF  // true
cpf2.isValidCPF  // true
cpf3.isValidCPF  // false

let cnpj1 = "25.559.813/0001-47"
let cnpj2 = "76.702.537/0001-65"
let cnpj3 = "22.222.222/2222-22"

cnpj1.isValidCNPJ  // true
cnpj2.isValidCNPJ  // true
cnpj3.isValidCNPJ  // false

1

Complement to @Leodabus' reply There’s a slight flaw in the CPF algorithm. The following CPF should be validated: 422.496.250-00 But it’s not being.

Correct return digit % 10 for return digit >= 10 ? 0 : digit

In the example quoted above, the rest of the Divisāo by 11 of the sum of the products results in 0, because Divisāo results in an entire quotient, so 11 - 0 = 11

Therefore, the rest of Divisāo of 11 by 10 is 1, when by the rules of CPF and CNPJ, numbers greater than 10 must return 0 as the check digit.

  • Thank you. I have corrected the error in the code that happened when I edited the reply.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.