Алгоритм Луна — это простая формула контрольной суммы, используемая для проверки различных идентификационных номеров, включая номера кредитных карт и IMEI. Это ценный инструмент для поддержания целостности данных и обнаружения ошибок при вводе. В этой статье рассматриваются различные реализации алгоритма Луна на Python, демонстрирующие различные стили программирования и их относительную эффективность.
Содержание
- Базовая реализация
- Функциональное разложение
- Итеративный подход (вложенные циклы)
- Расширенное функциональное программирование
- Заключение
Базовая реализация
Алгоритм Луна включает следующие шаги:
- Удвоить каждую вторую цифру справа налево.
- Если удвоенное значение превышает 9, вычесть 9.
- Суммировать все цифры.
- Если остаток от деления суммы на 10 равен 0, число является допустимым; в противном случае — недопустимым.
Вот простая реализация на 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"Число {number1} допустимо? {luhn_check(number1)}") # Вывод: True
print(f"Число {number2} допустимо? {luhn_check(number2)}") # Вывод: False
Функциональное разложение
Для повышения читаемости и удобства обслуживания мы можем разбить алгоритм на более мелкие, более специализированные функции:
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"Число {number1} допустимо (функционально)? {luhn_check_functional(number1)}") # Вывод: True
print(f"Число {number2} допустимо (функционально)? {luhn_check_functional(number2)}") # Вывод: False
Итеративный подход (вложенные циклы)
Итеративный подход с использованием вложенных циклов, хотя и менее эффективен, обеспечивает более наглядную пошаговую иллюстрацию алгоритма (преимущественно в образовательных целях):
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"Число {number1} допустимо (итеративно)? {luhn_check_iterative(number1)}") # Вывод: True
print(f"Число {number2} допустимо (итеративно)? {luhn_check_iterative(number2)}") # Вывод: False
Расширенное функциональное программирование
Использование функций map
и reduce
Python ещё больше улучшает функциональный подход:
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"Число {number1} допустимо (функциональное программирование)? {luhn_check_fp(number1)}") # Вывод: True
print(f"Число {number2} допустимо (функциональное программирование)? {luhn_check_fp(number2)}") # Вывод: False
Заключение
В этой статье были представлены различные реализации алгоритма Луна на Python, демонстрирующие различные парадигмы программирования. Хотя итеративный подход помогает в понимании, функциональные подходы, особенно расширенный, предлагают лучшую читаемость и эффективность для практического применения. Помните, что алгоритм Луна является контрольной суммой, а не полным решением для обеспечения безопасности; его следует использовать вместе с другими методами проверки.