# How to validate and calculate the control digit of a CPF

1

How does the algorithm that calculates the digit of a CPF (Brazilian Physical Register) work? And how is this calculation used to validate the CPF? If possible, I would like examples in Python.

asked by anonymous 19.05.2015 / 01:57

3

# How does the algorithm that calculates the digit of a CPF (Brazilian Physical Register) work?

According to Wilson Neto's answer , there is an explanation in this link . Basically, Module 11 is applied to a 9-digit number to generate the first check digit. The second check digit is generated from the original 9 digits, plus the first check digit.

# And how is this calculation used to validate the CPF?

The validation of the CPF is identical to the generation of the CPF. From the first 9 numbers, the two digits are generated. If they are the same as the input provided, the CPF is valid.

# If possible, I would like examples in Python.

Here is the code for validating CPF in Python.

``````#!/usr/bin/env python
#Djames Suhanko
import sys
try:
cpflimpo=sys.argv[1]
except IndexError:
print "Use %s NUMERO_DO_CPF" % sys.argv[0]
sys.exit()

if (len(cpflimpo) != 11 or not cpflimpo.isdigit()):
print "Formato errado. Tente de novo (apenas numeros)"
sys.exit()

digito = {}
digito[0] = 0
digito[1] = 0
a=10
total=0
for c in range(0,2):
for i in range(0,(8+c+1)):
total=total+int(cpflimpo[i])*a
a=a-1
digito[c]=int(11-(total%11))
a=11
total=0
if (int(cpflimpo[9]) == int(digito[0]) and int(cpflimpo[10]) == int(digito[1])):
print "CPF valido: ",
for i in (range(len(cpflimpo))):
if (i == 2 or i == 5):
sep=cpflimpo[i]+" ."
elif (i == 8):
sep=cpflimpo[i]+" -"
else:
sep=cpflimpo[i]
print "%s" % sep,
else:
print "CPF invalido"
``````

01.06.2015 / 17:23
2

Here is an example that can be used both on the command line and as a Python library, with doctests.

``````import re

def validar_cpf(cpf):
"""
Retorna o CPF válido sanitizado ou False.

# CPFs corretos
>>> validar_cpf('123.456.789-09')
'12345678909'
>>> validar_cpf('98765432100')
'98765432100'
>>> validar_cpf(' 123 123 123 87 ')
'12312312387'

# CPFs incorretos
>>> validar_cpf('12345678900')
False
>>> validar_cpf('1234567890')
False
>>> validar_cpf('')
False
>>> validar_cpf(None)
False
"""
cpf = ''.join(re.findall(r'\d', str(cpf)))

if not cpf or len(cpf) < 11:
return False

antigo = [int(d) for d in cpf]

# Gera CPF com novos dígitos verificadores e compara com CPF informado
novo = antigo[:9]
while len(novo) < 11:
resto = sum([v * (len(novo) + 1 - i) for i, v in enumerate(novo)]) % 11

digito_verificador = 0 if resto <= 1 else 11 - resto

if novo == antigo:
return cpf

return False

if __name__ == "__main__":
import sys

if len(sys.argv) != 2:
print("Uso: {} [CPF]".format(sys.argv[0]))
else:
cpf = validar_cpf(sys.argv[1])
print(cpf if cpf else "CPF Inválido")
``````

27.04.2018 / 23:37
0

One more solution would be:

pythonica

``````def validar_cpf(cpf: str) -> bool:

""" Efetua a validação do CPF, tanto formatação quando dígito verificadores.

Parâmetros:
cpf (str): CPF a ser validado

Retorno:
bool:
- Falso, quando o CPF não possuir o formato 999.999.999-99;
- Falso, quando o CPF não possuir 11 caracteres numéricos;
- Falso, quando os dígitos verificadores forem inválidos;

Exemplos:

>>> validate('529.982.247-25')
True
>>> validate('52998224725')
False
>>> validate('111.111.111-11')
False
"""

# Verifica a formatação do CPF
if not re.match(r'\d{3}\.\d{3}\.\d{3}-\d{2}', cpf):
return False

# Obtém apenas os números do CPF, ignorando pontuações
numbers = [int(digit) for digit in cpf if digit.isdigit()]

# Verifica se o CPF possui 11 números:
if len(numbers) != 11:
return False

# Validação do primeiro dígito verificador:
sum_of_products = sum(a*b for a, b in zip(numbers[0:9], range(10, 1, -1)))
expected_digit = (sum_of_products * 10 % 11) % 10
if numbers[9] != expected_digit:
return False

# Validação do segundo dígito verificador:
sum_of_products = sum(a*b for a, b in zip(numbers[0:10], range(11, 1, -1)))
expected_digit = (sum_of_products * 10 % 11) % 10
if numbers[10] != expected_digit:
return False

return True
``````

The implemented logic is exactly the same as that described in the other answers, but uses language tools to simplify the solution.

28.06.2018 / 14:22