Validación de NIFs y CIFs en Python 3
Hace más de un año escribí un par de entradas acerca de cómo realizar la validación de NIFs y CIFs en Python. He adaptado ese código para Python 3k y modificado un par de detalles.
import re
from functools import reduce
DNI = re.compile('(?P<dni>\d{8})(?P<letra>[A-Z])')
DNI_HYPHEN = re.compile('(?P<dni>\d{8})-(?P<letra>[A-Z])')
CIF = re.compile('(?P<letra>[A-H]|[J-N]|[P-S]|[UVW])(?P<numeracion>\d{7})(?P<control>[0-9A-J])')
CIF_HYPHEN = re.compile('(?P<letra>[A-H]|[J-N]|[P-S]|[UVW])-(?P<numeracion>\d{7})(?P<control>[0-9A-J])')
def validate_nif(value):
value = str(value).upper()
match = DNI.match(value)
if match is None:
match = DNI_HYPHEN.match(value)
if match is None:
raise Exception
dni = int(match.group('dni'))
letra = match.group('letra')
LETRAS_NIF = 'TRWAGMYFPDXBNJZSQVHLCKE'
if LETRAS_NIF[dni%23] != letra:
raise Exception
return '%s%s' % (dni, letra)
def validate_cif(value):
value = str(value).upper()
match = CIF.match(value)
if match is None:
match = CIF_HYPHEN.match(value)
if match is None:
raise Exception
LETRAS_CIF = 'ABCDEFGHJKLMNPQRSUVW' # Letras de CIF válidas
DC_NUMERICO_CIF = 'ABEH' # CIFs con número como dígito de control
DC_LETRA_CIF = 'KPQS' # CIFs con letra como dígito de control
ALPHA_CIF = 'JABCDEFGHI' # Correspondencia entre letra y dígito de control
# No todas las letras son válidas
if letra not in LETRAS_CIF:
raise Exception
# Obtenemos la información
letra = match.group('letra')
numeracion = match.group('numeracion')
control = match.group('control')
# Suma de los pares
a = reduce(lambda x, y: int(x)+int(y), numeracion[1::2])
# Suma de la suma de los dígitos de los impares * 2
b = sum(
[
int(reduce(lambda x,y: int(x)+int(y), impar))
for impar in map(lambda x: str(int(x)*2), numeracion[::2])
]
)
c = a + b
e = c % 10
d = (10-e) % 10
if letra in DC_NUMERICO_CIF:
d = str(d) # Es numérico
elif letra in DC_LETRA_CIF:
d = ALPHA_CIF[d] # Es una letra
else:
# Puede ser tanto letra como número
if control.isalpha():
d = ALPHA_CIF[d]
else:
d = str(d)
if d != control:
raise Exception
return '%s%s%s' % (letra, numeracion, control)
Tags
La teoría es cuando crees saber algo, pero no funciona.
La práctica es cuando algo funciona, pero no sabes por qué.
Los programadores combinan la teoría y la práctica:
Nada funciona y no saben por qué.
