associação pythonbrasil[11] django zope/plone planet Início Logado como (Entrar)

VerificadorDeCPF

Receita: Verificador de CPF

Esse módulo contém algumas funções e classes úteis para aplicações que envolvam cadastros e necessitem validar números de CPF antes de incluir no banco de dados. Além de útil, também é um bom exemplo de como otimizar código que lida com manipulação de números e strings, usando as funções sum(), map() e list compreensions.

Código

   1 #/usr/bin/env python
   2 # -*- coding:UTF-8 -*-
   3 # fonte: http://www.python.org.br/wiki/VerificadorDeCPF
   4 
   5 import re
   6 
   7 # traduz 123.456.789-10 para 12345678910
   8 _translate = lambda cpf: ''.join(re.findall("\d", cpf))
   9 
  10 def _exceptions(cpf):
  11     """Se o número de CPF estiver dentro das exceções é inválido
  12 
  13     """
  14     if len(cpf)!=11:
  15         return True
  16     else:
  17         s=''.join(str(x) for x in cpf)
  18         if s=='00000000000' or s=='11111111111' or s=='22222222222' or s=='33333333333' or s=='44444444444' or s=='55555555555' or s=='66666666666' or s=='77777777777' or s=='88888888888' or s=='99999999999':
  19             return True
  20     return False
  21 
  22 def _gen(cpf):
  23     """Gera o próximo dígito do número de CPF
  24 
  25     """
  26     res = []
  27     for i, a in enumerate(cpf):
  28         b = len(cpf) + 1 - i
  29         res.append(b * a)
  30 
  31     res = sum(res) % 11
  32 
  33     if res > 1:
  34         return 11 - res
  35     else:
  36         return 0
  37 
  38 
  39 class CPF(object):
  40 
  41     _gen = staticmethod(_gen)
  42     _translate = staticmethod(_translate)
  43     
  44     def __init__(self, cpf):
  45         """O argumento cpf pode ser uma string nas formas:
  46 
  47         12345678910
  48         123.456.789-10
  49 
  50         ou uma lista ou tuple
  51         [1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 0]
  52         (1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 0)
  53 
  54         """
  55         
  56         if isinstance(cpf, basestring):
  57             if not cpf.isdigit():
  58                cpf = self._translate(cpf)
  59             
  60         self.cpf = [int(x) for x in cpf]
  61 
  62     def __getitem__(self, index):
  63         """Retorna o dígito em index como string
  64 
  65         """
  66         
  67         return self.cpf[index]
  68 
  69     def __repr__(self):
  70         """Retorna uma representação 'real', ou seja:
  71 
  72         eval(repr(cpf)) == cpf
  73         
  74         """
  75         
  76         return "CPF('%s')" % ''.join(str(x) for x in self.cpf)
  77 
  78     def __eq__(self, other):
  79         """Provê teste de igualdade para números de CPF
  80 
  81         """
  82 
  83         return isinstance(other, CPF) and self.cpf == other.cpf
  84     
  85     def __str__(self):
  86         """Retorna uma representação do CPF na forma:
  87 
  88         123.456.789-10
  89 
  90         """
  91 
  92         d = iter("..-")
  93         s = map(str, self.cpf)
  94         for i in xrange(3, 12, 4):
  95             s.insert(i, d.next())
  96         r = ''.join(s)
  97         return r
  98 
  99     def isValid(self):
 100         """Valida o número de cpf
 101 
 102         """
 103         
 104         if _exceptions(self.cpf):
 105             return False
 106 
 107         s = self.cpf[:9]
 108         s.append(self._gen(s))
 109         s.append(self._gen(s))
 110         return s == self.cpf[:]

Exemplo de uso

   1 #/usr/bin/env python
   2 # -*- coding:UTF-8 -*-
   3 
   4 
   5 from cpf import CPF
   6 
   7 # Estes números foram gerados aleatoriamente :)
   8 
   9 VALIDO = "113.451.253-80"
  10 INVALIDO = "31354110274"
  11 
  12 # qualquer um dos dois formatos (com pontos ou não) pode ser usado
  13 
  14 valido = CPF(VALIDO)
  15 invalido = CPF(INVALIDO)
  16 
  17 assert valido.isValid()
  18 assert invalido.isValid()

Volta para CookBook.

Outro exemplo de validador de cpf em phyton

class Util(object):
    #Classe util com metodo de validacao de cpf.
    #Autor: Shalon Serpa (serpanet@gmail.com)
    def validaCpf(self,cpf,d1=0,d2=0,i=0):
        while i<10:
            d1,d2,i=(d1+(int(cpf[i])*(11-i-1)))%11 if i<9 else d1,(d2+(int(cpf[i])*(11-i)))%11,i+1
        return (int(cpf[9])==(11-d1 if d1>1 else 0)) and (int(cpf[10])==(11-d2 if d2>1 else 0))


#exemplo de uso

print Util().validaCpf("12345678901")


Pedro Werneck

edit 05/05/2010: Italo Maia

edit 19/04/2011: Moreno Cunha

edit 10/05/2013: Shalon Serpa