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