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

VerificadorDeCpfCnpjSimples

Receita: Verificador simplificado de CPF e CNPJ

O título "simplificado" é porque esse módulo não possui tantos recursos quanto as receitas originais em que foi baseado (VerificadorDeCpf e VerificadorDeCnpj); apenas retornam o CPF/CNPJ como uma string ("56068332551") se o CPF for válido ou False se for inválido.

A idéia foi unificar as duas receitas, tirar os testes repetidos e deixar o código menor e mais fácil de entender.

Código

   1 #!/usr/bin/env python
   2 # -*- coding: utf-8 -*-
   3 
   4 import re
   5 
   6 __all__ = ['validar_cpf', 'validar_cnpj']
   7 
   8 def validar_cpf(cpf):
   9     """
  10     Valida CPFs, retornando apenas a string de números válida.
  11 
  12     # CPFs errados
  13     >>> validar_cpf('abcdefghijk')
  14     False
  15     >>> validar_cpf('123')
  16     False
  17     >>> validar_cpf('')
  18     False
  19     >>> validar_cpf(None)
  20     False
  21     >>> validar_cpf('12345678900')
  22     False
  23 
  24     # CPFs corretos
  25     >>> validar_cpf('95524361503')
  26     '95524361503'
  27     >>> validar_cpf('955.243.615-03')
  28     '95524361503'
  29     >>> validar_cpf('  955 243 615 03  ')
  30     '95524361503'
  31     """
  32     cpf = ''.join(re.findall('\d', str(cpf)))
  33 
  34     if (not cpf) or (len(cpf) < 11):
  35         return False
  36 
  37     # Pega apenas os 9 primeiros dígitos do CPF e gera os 2 dígitos que faltam
  38     inteiros = map(int, cpf)
  39     novo = inteiros[:9]
  40 
  41     while len(novo) < 11:
  42         r = sum([(len(novo)+1-i)*v for i,v in enumerate(novo)]) % 11
  43 
  44         if r > 1:
  45             f = 11 - r
  46         else:
  47             f = 0
  48         novo.append(f)
  49 
  50     # Se o número gerado coincidir com o número original, é válido
  51     if novo == inteiros:
  52         return cpf
  53     return False
  54 
  55 def validar_cnpj(cnpj):
  56     """
  57     Valida CNPJs, retornando apenas a string de números válida.
  58 
  59     # CNPJs errados
  60     >>> validar_cnpj('abcdefghijklmn')
  61     False
  62     >>> validar_cnpj('123')
  63     False
  64     >>> validar_cnpj('')
  65     False
  66     >>> validar_cnpj(None)
  67     False
  68     >>> validar_cnpj('12345678901234')
  69     False
  70     >>> validar_cnpj('11222333000100')
  71     False
  72 
  73     # CNPJs corretos
  74     >>> validar_cnpj('11222333000181')
  75     '11222333000181'
  76     >>> validar_cnpj('11.222.333/0001-81')
  77     '11222333000181'
  78     >>> validar_cnpj('  11 222 333 0001 81  ')
  79     '11222333000181'
  80     """
  81     cnpj = ''.join(re.findall('\d', str(cnpj)))
  82 
  83     if (not cnpj) or (len(cnpj) < 14):
  84         return False
  85 
  86     # Pega apenas os 12 primeiros dígitos do CNPJ e gera os 2 dígitos que faltam
  87     inteiros = map(int, cnpj)
  88     novo = inteiros[:12]
  89 
  90     prod = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]
  91     while len(novo) < 14:
  92         r = sum([x*y for (x, y) in zip(novo, prod)]) % 11
  93         if r > 1:
  94             f = 11 - r
  95         else:
  96             f = 0
  97         novo.append(f)
  98         prod.insert(0, 6)
  99 
 100     # Se o número gerado coincidir com o número original, é válido
 101     if novo == inteiros:
 102         return cnpj
 103     return False
 104 
 105 if __name__ == "__main__":
 106     import doctest, sys
 107     result = doctest.testmod() #verbose=True)
 108     if result[0] == 0:
 109         print "OK!"
 110     else:
 111         print result

Volta para CookBook.


HumbertoDiogenes