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

Diferenças para "VerificadorDeCpf"

Diferenças entre as versões de 3 e 4
Revisão 3e 2003-11-19 04:09:48
Tamanho: 2870
Editor: PedroWerneck
Comentário:
Revisão 4e 2004-04-29 14:51:05
Tamanho: 3892
Editor: shasta091082
Comentário:
Deleções são marcadas assim. Adições são marcadas assim.
Linha 8: Linha 8:
{{{
#!python
#/usr/bin/env python
# -*- coding:UTF-8 -*-

def _gen(cpf):
    """Gera o próximo dígito do número de CPF

    """
    res = []
    for i in range(len(cpf)):
        a = cpf[i]
        b = (len(cpf) + 1 - i)
        res.append(b * a)

    res = sum(res) % 11
    if res > 1:
        return (11 - res)
    return 0


def _translate(cpf):
    """Traduz o número como string na forma:

    123.456.789-10

    para a forma:

    12345678910

    """
    
    i = xrange(256)
    t = [' '] * 256
    e = ''.join([chr(x) for x in i if not chr(x).isdigit()])
    
    for x in i:
        if chr(x).isdigit():
            t[x] = chr(x)
            
    return cpf.translate(''.join(t), e)



class CPF(object):

    def __init__(self, cpf):
        """O argumento cpf pode ser uma string nas formas:

        12345678910
        123.456.789-10

        ou uma lista ou tuple
        [1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 0]
        (1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 0)

        """
        
        if isinstance(cpf, basestring):
            if not cpf.isdigit():
               cpf = _translate(cpf)
            
        self.cpf = [int(x) for x in cpf]

    def __getitem__(self, index):
        """Retorna o dígito em index como string

        """
        
        return self.cpf[index]

    def __repr__(self):
        """Retorna uma representação 'real', ou seja:

        eval(repr(cpf)) == cpf
        
        """
        
        return "CPF('%s')" % ''.join([str(x) for x in self.cpf])

    def __eq__(self, other):
        """Provê teste de igualdade para números de CPF

        """

        if isinstance(other, CPF):
            return self.cpf == other.cpf
        return False
    
    def __str__(self):
        """Retorna uma representação do CPF na forma:

        123.456.789-10

        """

        d = iter("..-")
        s = map(str, self.cpf)
        for i in xrange(3, 12, 4):
            s.insert(i, d.next())
        r = ''.join(s)
        return r

    def verificar(self):
        """Valida o número de cpf

        """
        
        s = self.cpf[:9]
        s.append(_gen(s))
        s.append(_gen(s))
        return bool(s == self.cpf[:])




}}}



== Exemplo de uso ==
Linha 136: Linha 15:
from cpf import CPF """
Linha 138: Linha 17:
# Estes números foram gerados aleatoriamente :) Este módulo fornece uma classe wrapper para ser usada com números de
CPF, que além de oferecer um método simples de verificação, também
conta com métodos para comparação e conversão.
Linha 140: Linha 21:
VALIDO = "113.451.253-80"
INVALIDO = "31354110274"
Linha 143: Linha 22:
# qualquer um dos dois formatos (com pontos ou não) pode ser usado >>> a = CPF('56068332551')
>>> b = CPF('560.683.325-51')
>>> c = CPF((1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0))
>>> assert a.valido()
>>> assert b.valido()
>>> assert not c.valido()
>>> assert a == b
>>> assert not b == c
>>> assert not a == c
>>> assert eval(repr(a)) == a
>>> assert eval(repr(b)) == b
>>> assert eval(repr(c)) == c
>>> assert str(a) == \"560.683.325-51\"
>>> assert str(b) == str(a)
>>> assert str(c) == \"123.456.789-00\"
Linha 145: Linha 38:
valido = CPF(VALIDO)
invalido = CPF(INVALIDO)
"""
Linha 148: Linha 40:
assert valido.verificar()
assert not invalido.verificar()
Linha 151: Linha 41:


class CPF(object):

    def __init__(self, cpf):
        """Classe representando um número de CPF

        >>> a = CPF('95524361503')
        >>> b = CPF('955.243.615-03')
        >>> c = CPF([9, 5, 5, 2, 4, 3, 6, 1, 5, 0, 3])

        """
        if isinstance(cpf, basestring):
            if not cpf.isdigit():
                cpf = cpf.replace(".", "")
                cpf = cpf.replace("-", "")
        
            if not cpf.isdigit:
                raise ValueError("Valor não segue a forma xxx.xxx.xxx-xx")

        if len(cpf) < 11:
            raise ValueError("O número de CPF deve ter 11 digítos")
        
        self.cpf = map(int, cpf)


    def __getitem__(self, index):
        """Retorna o dígito em index como string

        >>> a = CPF('95524361503')
        >>> a[9] == '0'
        True
        >>> a[10] == '3'
        True
        >>> a[9] == 0
        False
        >>> a[10] == 3
        False

        """
        return str(self.cpf[index])

    def __repr__(self):
        """Retorna uma representação 'real', ou seja:

        eval(repr(cpf)) == cpf

        >>> a = CPF('95524361503')
        >>> print repr(a)
        CPF('95524361503')
        >>> eval(repr(a)) == a
        True
        
        """
        return "CPF('%s')" % ''.join([str(x) for x in self.cpf])

    def __eq__(self, other):
        """Provê teste de igualdade para números de CPF

        >>> a = CPF('95524361503')
        >>> b = CPF('955.243.615-03')
        >>> c = CPF('123.456.789-00')
        >>> a == b
        True
        >>> a != c
        True
        >>> b != c
        True

        """
        if isinstance(other, CPF):
            return self.cpf == other.cpf
        return False
    
    def __str__(self):
        """Retorna uma string do CPF na forma com pontos e traço

        >>> a = CPF('95524361503')
        >>> str(a)
        '955.243.615-03'
        

        """
        d = ((3, "."), (7, "."), (11, "-"))
        s = map(str, self.cpf)
        for i, v in d:
            s.insert(i, v)
        r = ''.join(s)
        return r

    def valido(self):
        """Valida o número de cpf

        >>> a = CPF('95524361503')
        >>> a.valido()
        True
        >>> b = CPF('12345678900')
        >>> b.valido()
        False

        """
        cpf = self.cpf[:9]
        # pegamos apenas os 9 primeiros dígitos do cpf e geramos os
        # dois dígitos que faltam
        while len(cpf) < 11:

            r = sum(map(lambda(i,v):(len(cpf)+1-i)*v,enumerate(cpf))) % 11

            if r > 1:
                f = 11 - r
            else:
                f = 0
            cpf.append(f)

        # se o número com os digítos faltantes coincidir com o número
        # original, então ele é válido
        return bool(cpf == self.cpf)



if __name__ == "__main__":

    import doctest, sys
    doctest.testmod(sys.modules[__name__])

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..

Código

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

Volta para CookBook.


PedroWerneck