Article image
Carlos Soares
Carlos Soares17/11/2022 12:12
Compartilhe

Como Fazer uma Validação de CPF com Python

  • #Python

A validação de CPF é baseada na verificação dos nove primeiros dígitos do CPF, e comparada com os dois últimos dígitos.

Ela é segmentada em duas partes, na qual vou explicar a seguir:

Primeira Validação: Multiplicamos os nove primeiros dígitos do CPF um a um pelos valores decrescentes de 10 até 2, conforme o exemplo a seguir para o CPF 123.456.789-10, onde multiplicamos:

1 X 10 = 10 - 2 X 9 = 18 - 3 X 8 = 24

e assim sucessivamente, ao final pegamos o total da soma destes nove resultados e dividimos por 11.

Se o resto desta soma for menor ou igual a 1 e o penúltimo dígito do CPF deve ser igual ao numeral zero... Entretanto se o resto for maior de 2, então o penúltimo dígito do CPF deve ser igual a diferença entre o numero 11 menos o valor do resto obtido.

Segunda Validação: Faremos da mesma forma da primeira validação, sendo que a multiplicação será a partir do número 11 conforme mostrado a seguir no CPF do exemplo 123.456.789-10:

1 X 11 = 11 - 2 X 10 = 20 - 3 X 9 = 27

e assim sucessivamente... contudo desta vez adicionaremos na soma o primeiro digito verificador, sendo assim teremos a multiplicação dos dez primeiros dígitos do CPF.

Se o resto da divisão for menor ou igual a 1 então o ultimo digito verificador deve ser igual a zero... Entretanto se o resto da divisão for maior ou igual a dois, faremos a diferença entre o o numeral 11 e o resto da divisão, onde este deve ser igual o último dígito do CPF para que este seja válido.

Segue o código abaixo:

NOVO_CPF = list(input("Digite um CPF para ser validado >>>"))
NOVO_CPF_STRING = " ".join(NOVO_CPF)

def validacao_cpf():
  if len(NOVO_CPF) == 11:
      primeiro1 = int(NOVO_CPF[0]) * 10
      primeiro2 = int(NOVO_CPF[1]) * 9
      primeiro3 = int(NOVO_CPF[2]) * 8
      primeiro4 = int(NOVO_CPF[3]) * 7
      primeiro5 = int(NOVO_CPF[4]) * 6
      primeiro6 = int(NOVO_CPF[5]) * 5
      primeiro7 = int(NOVO_CPF[6]) * 4
      primeiro8 = int(NOVO_CPF[7]) * 3
      primeiro9 = int(NOVO_CPF[8]) * 2

      seg_primeiro1 = int(NOVO_CPF[0]) * 11
      seg_primeiro2 = int(NOVO_CPF[1]) * 10
      seg_primeiro3 = int(NOVO_CPF[2]) * 9
      seg_primeiro4 = int(NOVO_CPF[3]) * 8
      seg_primeiro5 = int(NOVO_CPF[4]) * 7
      seg_primeiro6 = int(NOVO_CPF[5]) * 6
      seg_primeiro7 = int(NOVO_CPF[6]) * 5
      seg_primeiro8 = int(NOVO_CPF[7]) * 4
      seg_primeiro9 = int(NOVO_CPF[8]) * 3
      seg_primeiro10 = int(NOVO_CPF[9]) * 2

      soma_validacao = (primeiro1 + primeiro2 + primeiro3 + primeiro4 + primeiro5 + primeiro6 + primeiro7 + primeiro8 + primeiro9)
      divisao_soma = (soma_validacao // 11)
      resto = (soma_validacao - (11 * divisao_soma))

      soma_validacao_2 = (seg_primeiro1 + seg_primeiro2 + seg_primeiro3 + seg_primeiro4 + seg_primeiro5 + seg_primeiro6 + seg_primeiro7 + seg_primeiro8 + seg_primeiro9 + seg_primeiro10)
      divisao_soma_2 = (soma_validacao_2 // 11)
      resto_2 = (soma_validacao_2 - (11 * divisao_soma_2))

      val_1 = False
      val_2 = False
      val_3 = False
      val_4 = False

      if(resto <=1) and (NOVO_CPF[9] == 0):
          val_1 = True
      if( resto >=2 and resto < 10) and (11 - resto == NOVO_CPF[9]):
          val_2 = True
      if( resto_2 <=1 ) and (NOVO_CPF[10] == 0):
          val_3 = True
      if ( resto_2 >=2 and resto_2 < 10 ) and (11 - resto_2 == NOVO_CPF[10]):
          val_4 = True
      else: ()

      if (val_1 == True or val_2 == True) and (val_3 == True or val_4 == True):
          print(f"O CPF número: {NOVO_CPF_STRING} é válido !")
      else:
          print(f"O CPF número: {NOVO_CPF_STRING} é inválido, tente novamente.")

      #Abaixo Validação dos estado de origem do CPF
      if NOVO_CPF[8] == 1:
          print("Seu CPF é originário do estado do Distrito Federal, Goiás, Mato Grosso do Sul ou Tocantins")
      elif NOVO_CPF[8] == 2:
          print("Seu CPF é originário do estado do Pará, Amazonas, Acre, Amapá, Rondônia ou Roraima")
      elif NOVO_CPF[8] == 3:
          print("Seu CPF é originário do estado do Ceará, Maranhão ou Piauí")
      elif NOVO_CPF[8] == 4:
          print("Seu CPF é originário do estado de Pernambuco, Rio Grande do Norte, Paraíba ou Alagoas")
      elif NOVO_CPF[8] == 5:
          print("Seu CPF é originário do estado da Bahia; e Sergipe")
      elif NOVO_CPF[8] == 6:
          print("Seu CPF é originário de Minas Gerais")
      elif NOVO_CPF[8] == 7:
          print("Seu CPF é originário do estado do Rio de Janeiro ou Espírito Santo")
      elif NOVO_CPF[8] == 8:
          print("Seu CPF é originário do estado de São Paulo")
      elif NOVO_CPF[8] == 9:
          print("Seu CPF é originário do estado do Paraná ou Santa Catarina")
      else:
          print("Seu CPF é de origem do estado do Rio Grande do Sul")

  else: 
      print(f"O CPF número: {NOVO_CPF_STRING} é inválido, tente novamente.")

validacao_cpf()

Este código acima foi elaborado de uma forma bem explicativa, para que seja de fácil compreensão por todos, inclusive que não conhece a linguagem Python.

Abaixo segue o mesmo código Python elaborado de forma "correta".

Vamos disseminar o conhecimento.

import re

def validador():
  cpf = str(input("Digite um CPF para ser validado ao lado. >>>"))

  #Retira apenas os dígitos do CPF, ignorando os caracteres especiais
  numeros = [int(digito) for digito in cpf if digito.isdigit()]
  
  formatacao = False
  quant_digitos = False
  validacao1 = False
  validacao2 = False

  #Verifica a estrutura do CPF (111.222.333-44)
  if re.match(r'\d{3}\.\d{3}\.\d{3}-\d{2}', cpf):
      formatacao = True

  if len(numeros) == 11:
      quant_digitos = True
  
      soma_produtos = sum(a*b for a, b in zip (numeros[0:9], range (10, 1, -1)))
      digito_esperado = (soma_produtos * 10 % 11) % 10
      if numeros[9] == digito_esperado:
          validacao1 = True

      soma_produtos1 = sum(a*b for a, b in zip(numeros [0:10], range (11, 1, -1)))
      digito_esperado1 = (soma_produtos1 *10 % 11) % 10
      if numeros[10] == digito_esperado1:
          validacao2 = True

      if quant_digitos == True and formatacao == True and validacao1 == True and validacao2 == True:
          print(f"O CPF {cpf} é válido.")
      else:
          print(f"O CPF {cpf} não é válido... Tente outro CPF...")

  else:
      print(print(f"O CPF {cpf} não é válido... Tente outro CPF..."))

validador()

Vamos Disseminar o Conhecimento.

Gratidão a DIO por me proporcionar a aprender um pouco mais a cada dia...

Compartilhe
Comentários (2)
Ronan Martin
Ronan Martin - 17/11/2022 17:56

Legal sua explicação Carlos, eu estou estudando programação a um pouco mais que 3 meses. Comecei com a linguagem GO, e curiosamente o primeiro serviço que escrevi sozinho, sem ajuda de tutorial, foi exatamente para fazer essa tarefa, mas em GO claro. Vou compartilhar aqui meu código, fica como uma segunda alternativa pra quem quiser examinar, e vou salvar seu código para quando for aprender Python.


package main


import (

"encoding/json"

"fmt"

"log"

"net/http"

"strconv"

"strings"

)


func main() {

fmt.Println("Iniciando o servidor REST na porta 8080")

fmt.Println("Ex.: http://localhost:8080/valida-cpf?numero=91468384066")


http.HandleFunc("/valida-cpf", ValidaCPF)


log.Fatal(http.ListenAndServe(":8080", nil))

}


func converteCPF(cpfstr string) ([]int, error) {

var cpfint []int

for _, numstr := range cpfstr {

numstr, err := strconv.Atoi(string(numstr))

if err != nil {

return nil, err

}

cpfint = append(cpfint, numstr)

}

return cpfint, nil

}


func recalculaCPF(cpfint []int) []int {

// duplica os 9 primeiros digitos do cpfint para uma nova variavel

var cpfpart []int

cpfpart = append(cpfpart, cpfint[:9]...)


// calcula digito verificador 1

multiplicador := 10

total := 0


for _, v := range cpfpart {

total += v * multiplicador

multiplicador--

}


digito1 := 11 - (total % 11)


switch {

case digito1 >= 10:

cpfpart = append(cpfpart, 0)

case digito1 < 10:

cpfpart = append(cpfpart, digito1)

}


// calcula digito verificador 2

multiplicador = 11

total = 0


for _, v := range cpfpart {

total += v * multiplicador

multiplicador--

}


digito2 := 11 - (total % 11)


switch {

case digito2 >= 10:

cpfpart = append(cpfpart, 0)

case digito2 < 10:

cpfpart = append(cpfpart, digito2)

}


return cpfpart

}


func comparaCPFs(cpf1int []int, cpf2int []int) bool {

cpf1str := make([]string, len(cpf1int))

for k, v := range cpf1int {

cpf1str[k] = strconv.Itoa(v)

}


cpf2str := make([]string, len(cpf2int))

for k, v := range cpf2int {

cpf2str[k] = strconv.Itoa(v)

}


cpf1 := strings.Join(cpf1str, "")

cpf2 := strings.Join(cpf2str, "")


return cpf1 == cpf2

}


func formataCPF(cpfint []int) string {

cpfstr := make([]string, len(cpfint))

for k, v := range cpfint {

cpfstr[k] = strconv.Itoa(v)

}


part1 := strings.Join(cpfstr[:3], "")

part2 := strings.Join(cpfstr[3:6], "")

part3 := strings.Join(cpfstr[6:9], "")

part4 := strings.Join(cpfstr[9:], "")


return fmt.Sprintf("%s.%s.%s-%s", part1, part2, part3, part4)

}


type Resposta struct {

Valido  bool  `json:"valido"`

Formatado string `json:"formatado"`

}


func ValidaCPF(rw http.ResponseWriter, r *http.Request) {

enc := json.NewEncoder(rw)


cpfstr := r.URL.Query().Get("numero")


cpfint, err := converteCPF(cpfstr)

if err != nil {

enc.Encode("CPF invalido")

return

}


recalculado := recalculaCPF(cpfint)


valido := comparaCPFs(cpfint, recalculado)

formatado := formataCPF(cpfint)


rw.Header().Set("Access-Control-Allow-Origin", "*")


enc.Encode(Resposta{valido, formatado})

}

Carlos Soares
Carlos Soares - 18/11/2022 09:12

Obrigado por contribuir...


O legal da programação é que independente de conhecer ou não a linguagem a fundo, a parte lógica é bem parecida é fácil de entender.