O algoritmo de Luhn é uma fórmula de checksum simples usada para validar vários números de identificação, incluindo números de cartão de crédito e números IMEI. É uma ferramenta valiosa para manter a integridade dos dados e detectar erros durante a entrada. Este artigo explora diferentes implementações em Python do algoritmo de Luhn, mostrando vários estilos de programação e sua eficiência relativa.
Sumário
- Implementação Básica
- Decomposição Funcional
- Abordagem Iterativa (Loops Aninhados)
- Programação Funcional Avançada
- Conclusão
Implementação Básica
O algoritmo de Luhn envolve estas etapas:
- Dobre cada segundo dígito da direita para a esquerda.
- Se o valor dobrado exceder 9, subtraia 9.
- Some todos os dígitos.
- Se o total módulo 10 for 0, o número é válido; caso contrário, é inválido.
Aqui está uma implementação direta em 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"Is {number1} valid? {luhn_check(number1)}") # Output: True
print(f"Is {number2} valid? {luhn_check(number2)}") # Output: False
Decomposição Funcional
Para melhorar a legibilidade e a manutenibilidade, podemos dividir o algoritmo em funções menores e mais focadas:
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"Is {number1} valid (functional)? {luhn_check_functional(number1)}") # Output: True
print(f"Is {number2} valid (functional)? {luhn_check_functional(number2)}") # Output: False
Abordagem Iterativa (Loops Aninhados)
Uma abordagem iterativa usando loops aninhados, embora menos eficiente, fornece uma ilustração passo a passo mais clara do algoritmo (principalmente para fins educacionais):
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"Is {number1} valid (iterative)? {luhn_check_iterative(number1)}") # Output: True
print(f"Is {number2} valid (iterative)? {luhn_check_iterative(number2)}") # Output: False
Programação Funcional Avançada
Aproveitando as funções map
e reduce
do Python, aprimora-se ainda mais a abordagem 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"Is {number1} valid (functional programming)? {luhn_check_fp(number1)}") # Output: True
print(f"Is {number2} valid (functional programming)? {luhn_check_fp(number2)}") # Output: False
Conclusão
Este artigo apresentou várias implementações em Python do algoritmo de Luhn, demonstrando diferentes paradigmas de programação. Embora a abordagem iterativa ajude na compreensão, as abordagens funcionais, particularmente a avançada, oferecem melhor legibilidade e eficiência para aplicações práticas. Lembre-se de que o algoritmo de Luhn é um checksum, não uma solução de segurança completa; ele deve ser usado com outros métodos de validação.