Receita: Verificador de CNPJ
Quase tudo é cópia do script de verificação de CPF do Pedro Werneck, mas voltado para CNPJ (se for encontrada alguma falha sinta-se à vontade para corrigir ou me informar).
Ver também: VerificadorDeCpfCnpjSimples.
Código
1 #/usr/bin/env python
2 # -*- coding:UTF-8 -*-
3
4 """
5 Este módulo fornece uma classe wrapper para ser usada com números de
6 CNPJ(CGC), que além de oferecer um método simples de verificação, também
7 conta com métodos para comparação e conversão.
8
9
10 >>> a = CNPJ('11222333000181')
11 >>> b = CNPJ('11.222.333/0001-81')
12 >>> c = CNPJ([1, 1, 2, 2, 2, 3, 3, 3, 0, 0, 0, 1, 8, 2])
13 >>> assert a.valido()
14 >>> assert b.valido()
15 >>> assert not c.valido()
16 >>> assert a == b
17 >>> assert not b == c
18 >>> assert not a == c
19 >>> assert eval(repr(a)) == a
20 >>> assert eval(repr(b)) == b
21 >>> assert eval(repr(c)) == c
22 >>> assert str(a) == \"11.222.333/0001-81\"
23 >>> assert str(b) == str(a)
24 >>> assert str(c) == \"11.222.333/0001-82\"
25 """
26
27
28 class CNPJ(object):
29
30 def __init__(self, cnpj):
31 """Classe representando um número de CNPJ
32
33 >>> a = CNPJ('11222333000181')
34 >>> b = CNPJ('11.222.333/0001-81')
35 >>> c = CNPJ([1, 1, 2, 2, 2, 3, 3, 3, 0, 0, 0, 1, 8, 2])
36
37 """
38 try:
39 basestring
40 except:
41 basestring = (str, unicode)
42
43 if isinstance(cnpj, basestring):
44 if not cnpj.isdigit():
45 cnpj = cnpj.replace(".", "")
46 cnpj = cnpj.replace("-", "")
47 cnpj = cnpj.replace("/", "")
48
49 if not cnpj.isdigit:
50 raise ValueError("Valor não segue a forma xx.xxx.xxx/xxxx-xx")
51
52 if len(cnpj) < 14:
53 raise ValueError("O número de CNPJ deve ter 14 digítos")
54
55 self.cnpj = map(int, cnpj)
56
57
58 def __getitem__(self, index):
59 """Retorna o dígito em index como string
60
61 >>> a = CNPJ('11222333000181')
62 >>> a[9] == '0'
63 True
64 >>> a[10] == '0'
65 True
66 >>> a[9] == 0
67 False
68 >>> a[10] == 0
69 False
70
71 """
72 return str(self.cnpj[index])
73
74 def __repr__(self):
75 """Retorna uma representação 'real', ou seja:
76
77 eval(repr(cnpj)) == cnpj
78
79 >>> a = CNPJ('11222333000181')
80 >>> print repr(a)
81 CNPJ('11222333000181')
82 >>> eval(repr(a)) == a
83 True
84
85 """
86 return "CNPJ('%s')" % ''.join([str(x) for x in self.cnpj])
87
88 def __eq__(self, other):
89 """Provê teste de igualdade para números de CNPJ
90
91 >>> a = CNPJ('11222333000181')
92 >>> b = CNPJ('11.222.333/0001-81')
93 >>> c = CNPJ([1, 1, 2, 2, 2, 3, 3, 3, 0, 0, 0, 1, 8, 2])
94 >>> a == b
95 True
96 >>> a != c
97 True
98 >>> b != c
99 True
100
101 """
102 if isinstance(other, CNPJ):
103 return self.cnpj == other.cnpj
104 return False
105
106 def __str__(self):
107 """Retorna uma string do CNPJ na forma com pontos e traço
108
109 >>> a = CNPJ('11222333000181')
110 >>> str(a)
111 '11.222.333/0001-81'
112
113 """
114 d = ((2, "."), (6, "."), (10, "/"), (15, "-"))
115 s = map(str, self.cnpj)
116 for i, v in d:
117 s.insert(i, v)
118 r = ''.join(s)
119 return r
120
121 def valido(self):
122 """Valida o número de cnpj
123
124 >>> a = CNPJ('11.222.333/0001-81')
125 >>> a.valido()
126 True
127 >>> b = CNPJ('11222333000182')
128 >>> b.valido()
129 False
130
131 """
132 cnpj = self.cnpj[:12]
133 prod = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]
134 # pegamos apenas os 9 primeiros dígitos do CNPJ e geramos os
135 # dois dígitos que faltam
136 while len(cnpj) < 14:
137
138 r = sum([x*y for (x, y) in zip(cnpj, prod)])%11
139
140 if r > 1:
141 f = 11 - r
142 else:
143 f = 0
144 cnpj.append(f)
145 prod.insert(0, 6)
146
147 # se o número com os digítos faltantes coincidir com o número
148 # original, então ele é válido
149 return bool(cnpj == self.cnpj)
150
151 if __name__ == "__main__":
152 import doctest, sys
153 doctest.testmod(sys.modules[__name__])
Volta para CookBook.