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 _gen(cpf):
11 """Gera o próximo dígito do número de CPF
12
13 """
14 res = []
15 for i in range(len(cpf)):
16 a = cpf[i]
17 b = len(cpf) + 1 - i
18 res.append(b * a)
19
20 res = sum(res) % 11
21
22 if res > 1:
23 return 11 - res
24 else:
25 return 0
26
27
28 class CPF(object):
29
30 _gen = staticmethod(_gen)
31 _translate = staticmethod(_translate)
32
33 def __init__(self, cpf):
34 """O argumento cpf pode ser uma string nas formas:
35
36 12345678910
37 123.456.789-10
38
39 ou uma lista ou tuple
40 [1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 0]
41 (1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 0)
42
43 """
44
45 if isinstance(cpf, basestring):
46 if not cpf.isdigit():
47 cpf = self._translate(cpf)
48
49 self.cpf = [int(x) for x in cpf]
50
51 def __getitem__(self, index):
52 """Retorna o dígito em index como string
53
54 """
55
56 return self.cpf[index]
57
58 def __repr__(self):
59 """Retorna uma representação 'real', ou seja:
60
61 eval(repr(cpf)) == cpf
62
63 """
64
65 return "CPF('%s')" % ''.join([str(x) for x in self.cpf])
66
67 def __eq__(self, other):
68 """Provê teste de igualdade para números de CPF
69
70 """
71
72 if isinstance(other, CPF):
73 return self.cpf == other.cpf
74 return False
75
76 def __str__(self):
77 """Retorna uma representação do CPF na forma:
78
79 123.456.789-10
80
81 """
82
83 d = iter("..-")
84 s = map(str, self.cpf)
85 for i in xrange(3, 12, 4):
86 s.insert(i, d.next())
87 r = ''.join(s)
88 return r
89
90 def isValid(self):
91 """Valida o número de cpf
92
93 """
94
95 s = self.cpf[:9]
96 s.append(self._gen(s))
97 s.append(self._gen(s))
98 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.
Pedro Werneck
edit 05/05/2010: Italo Maia