Python Programming

Dominando el Algoritmo de Luhn en Python: Cuatro Implementaciones

Spread the love

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

El algoritmo de Luhn implica estos pasos:

  1. Duplicar cada segundo dígito de derecha a izquierda.
  2. Si el valor duplicado excede 9, restar 9.
  3. Sumar todos los dígitos.
  4. 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.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *