El algoritmo de Luhn es una fórmula de suma de verificación simple utilizada para validar varios números de identificación, incluidos los números de tarjetas de crédito y los números IMEI. Es una herramienta valiosa para mantener la integridad de los datos y detectar errores durante la entrada. Este artículo explora diferentes implementaciones en Python del algoritmo de Luhn, mostrando varios estilos de programación y su eficiencia relativa.
Tabla de contenido
- Implementación básica
- Descomposición funcional
- Enfoque iterativo (bucles anidados)
- Programación funcional avanzada
- Conclusión
Implementación básica
El algoritmo de Luhn implica estos pasos:
- Duplicar cada segundo dígito de derecha a izquierda.
- Si el valor duplicado excede 9, restar 9.
- Sumar todos los dígitos.
- Si el total módulo 10 es 0, el número es válido; de lo contrario, es inválido.
Aquí hay una implementación directa en Python:
def luhn_check(number):
try:
digits = [int(d) for d in str(number)]
except ValueError:
return False
odd_sum = sum(digits[-1::-2])
even_sum = sum([sum(divmod(2 * d, 10)) for d in digits[-2::-2]])
return (odd_sum + even_sum) % 10 == 0
number1 = 49927398716
number2 = 1234567890123456
print(f"¿Es {number1} válido? {luhn_check(number1)}") # Salida: True
print(f"¿Es {number2} válido? {luhn_check(number2)}") # Salida: False
Descomposición funcional
Para mejorar la legibilidad y el mantenimiento, podemos dividir el algoritmo en funciones más pequeñas y específicas:
def double_digit(digit):
return sum(divmod(2 * digit, 10))
def sum_digits(digits):
return sum(digits)
def luhn_check_functional(number):
try:
digits = [int(d) for d in str(number)]
except ValueError:
return False
odd_sum = sum_digits(digits[-1::-2])
even_sum = sum_digits([double_digit(d) for d in digits[-2::-2]])
return (odd_sum + even_sum) % 10 == 0
print(f"¿Es {number1} válido (funcional)? {luhn_check_functional(number1)}") # Salida: True
print(f"¿Es {number2} válido (funcional)? {luhn_check_functional(number2)}") # Salida: False
Enfoque iterativo (bucles anidados)
Un enfoque iterativo usando bucles anidados, aunque menos eficiente, proporciona una ilustración paso a paso más clara del algoritmo (principalmente con fines educativos):
def luhn_check_iterative(number):
try:
digits = [int(x) for x in str(number)]
except ValueError:
return False
total = 0
for i in range(len(digits) - 1, -1, -1):
if i % 2 == 0:
total += digits[i]
else:
doubled = digits[i] * 2
if doubled > 9:
doubled -= 9
total += doubled
return total % 10 == 0
print(f"¿Es {number1} válido (iterativo)? {luhn_check_iterative(number1)}") # Salida: True
print(f"¿Es {number2} válido (iterativo)? {luhn_check_iterative(number2)}") # Salida: False
Programación funcional avanzada
Aprovechando las funciones map
y reduce
de Python, se mejora aún más el enfoque funcional:
from functools import reduce
def luhn_check_fp(number):
try:
digits = list(map(int, str(number)))
except ValueError:
return False
odd_sum = sum(digits[-1::-2])
even_sum = reduce(lambda x, y: x + y, map(lambda d: sum(divmod(2 * d, 10)), digits[-2::-2]))
return (odd_sum + even_sum) % 10 == 0
print(f"¿Es {number1} válido (programación funcional)? {luhn_check_fp(number1)}") # Salida: True
print(f"¿Es {number2} válido (programación funcional)? {luhn_check_fp(number2)}") # Salida: False
Conclusión
Este artículo presentó varias implementaciones en Python del algoritmo de Luhn, demostrando diferentes paradigmas de programación. Si bien el enfoque iterativo ayuda a la comprensión, los enfoques funcionales, particularmente el avanzado, ofrecen una mejor legibilidad y eficiencia para aplicaciones prácticas. Recuerde que el algoritmo de Luhn es una suma de verificación, no una solución de seguridad completa; debe usarse con otros métodos de validación.