Re: [Python-es] validación cif
Cesar Ortiz
cesar en ortiz.name
Mie Abr 29 15:50:23 CEST 2009
Bueno... para quien le pueda interesar... creo que ya lo tengo.
Voy a echarle un ojo a la implementación de django, a ver si es correcta.
Chema tu implementación creo que no es correcta, creo que al menos tiene un
error en la comprobación de _testNIFJuridica() cuando compruebas si las
posiciones son pares o impares. Yo cometí el mismo error. La cuestión es que
si tomamos como primera posición el 2, estas cambiando el algormitmo. La
primera posición tendría que ser el 1 => tienes los calculos de impar/par
cambiados.
Adjunto el código,
Saludos!
PD: Cuando digo que un nif o cif está normalizado, me refiero a que están
todas las letras/digitos seguidos sin ningún tipo de separador (ej:
P1234567A))
#-------------------------------------------------------------------------------
# Validador
#-------------------------------------------------------------------------------
class Validador(object):
TABLA_NIF='TRWAGMYFPDXBNJZSQVHLCKE' # Valores para validar el NIF
CLAVES_CIF='PQS' + 'ABEH' + 'CDFGJRUVNW'
CLAVES_NIF1 = 'LKM' # Son especiales, se validan
# como CIFs
CLAVES_NIF2 = 'XYZ'
CLAVES_NIF = CLAVES_NIF1 + CLAVES_NIF2
CONTROL_CIF_LETRA = 'KPQS'
CONTROL_CIF_NUMERO = 'ABEH'
EQUIVALENCIAS_CIF = {1:'A', 2:'B', 3:'C', 4:'D', 5:'E', 6:'F', 7:'G',
8:'H', 9:'I', 10:'J', 0:'J'}
#-------------------------------------------------------------------------------
def validarNIF(self,valor):
"""
Nos indica si un NIF es valido.
El valor debe estar normalizado
@note:
- ante cualquier problema se valida como False
"""
bRet = False
if len(valor) == 9:
try:
if valor[0] in self.__class__.CLAVES_NIF1:
bRet = self.validarCIF(valor)
else:
num=None
if valor[0] in self.__class__.CLAVES_NIF2:
pos = self.__class__.CLAVES_NIF2.find(valor[0])
sNum = str(pos) + valor[1:-1]
num=int(sNum)
elif valor[0].isdigit():
num=int(valor[:-1])
if num!=None and self.__class__.TABLA_NIF[num%23] == valor[-1]:
bRet=True
except:
pass
return bRet
#-------------------------------------------------------------------------------
def validarCIF(self,valor):
"""
Nos indica si un CIF es valido.
El valor debe estar normalizado
@note:
- ante cualquier problema se valida como False
"""
bRet = False
if len(valor) == 9:
v0 = valor[0]
if v0 in self.__class__.CLAVES_NIF1 or v0 in
self.__class__.CLAVES_CIF:
try:
sumPar = 0
sumImpar = 0
for i in xrange(1,8):
if i % 2:
v = int(valor[i]) * 2
if v > 9: v = 1 + (v - 10)
sumImpar += v
else:
v = int(valor[i])
sumPar += v
suma = sumPar + sumImpar
e = suma % 10
d = 10 - e
letraCif = self.__class__.EQUIVALENCIAS_CIF[d]
if valor[0] in self.__class__.CONTROL_CIF_LETRA:
if valor[-1] == letraCif: bRet = True
elif valor[0] in self.__class__.CONTROL_CIF_NUMERO:
if d == 10: d = 0
if valor[-1] == str(d): bRet = True
else:
if d == 10: d = 0
if valor[-1] == str(d) or valor[-1] == letraCif: bRet = True
except:
pass
return bRet
#-------------------------------------------------------------------------------
def validar(self,valor):
"""
Nos valida un CIF o un NIF
"""
bRet = False
if len(valor) == 9:
if valor[0] in self.__class__.CLAVES_NIF or valor[0].isdigit():
bRet = self.validarNIF(valor)
else:
bRet = self.validarCIF(valor)
return bRet
#-------------------------------------------------------------------------------
2009/4/28 Cesar Ortiz <cesar en ortiz.name>
> Gracias!
>
> Anotada la nueva url para poder acceder a los archivos.
> Echaré un ojo a ese codigo para contrastarlo con una implementación que he
> hecho.
> Sólo vi online la de la url de antes y de fijo que está mal.
>
> Un saludos.
>
> 2009/4/28 Chema Cortes <pych3m4 en gmail.com>
>
> El día 28 de abril de 2009 18:10, Luis Peralta <peralta en aditel.org>
>> escribió:
>> > Hola César,
>> >
>> > El día 28 de abril de 2009 15:45, Cesar Ortiz <cesar en ortiz.name>
>> escribió:
>>
>> No me ha llegado este mensaje :-(
>>
>> Lo veo en gmane.org, que es una alternativa para cuando falle la web
>> de la lista:
>>
>> http://news.gmane.org/gmane.comp.python.general.castellano
>>
>> >>
>> >> Que creo erronea. ¿Sabeis de alguna implementación que esté online?
>> >
>> > La de django, ESIdentityCardNumberField:
>> >
>> >
>> http://code.djangoproject.com/browser/django/trunk/django/contrib/localflavor/es/forms.py
>> >
>> > No la he usado, pero sé que está ahí ;)
>>
>> Aún mantengo una vieja implementación:
>>
>> http://ch3m4.org/pystore/Calcnif.py
>>
>>
>> Tengo pendiente darle un buen repaso para adaptarla al nuevo estilo
>> python.
>>
>> Fallos de esta implementación (y la de django):
>>
>> - No admite los NIEs que empiezan por 'Y'
>> - Muy pronto aparecerán NIFs de 9 dígitos+letra (pasaremos de los 100
>> millones)
>> _______________________________________________
>> Lista de correo Python-es
>> http://listas.aditel.org/listinfo/python-es
>> FAQ: http://listas.aditel.org/faqpyes
>>
>
>
_______________________________________________
Lista de correo Python-es
http://listas.aditel.org/listinfo/python-es
FAQ: http://listas.aditel.org/faqpyes
Más información sobre la lista de distribución Python-es