Python Programming

Мастерство алгоритма Луна в Python: четыре реализации

Spread the love

Алгоритм Луна — это простая формула контрольной суммы, используемая для проверки различных идентификационных номеров, включая номера кредитных карт и IMEI. Это ценный инструмент для поддержания целостности данных и обнаружения ошибок при вводе. В этой статье рассматриваются различные реализации алгоритма Луна на Python, демонстрирующие различные стили программирования и их относительную эффективность.

Содержание

Базовая реализация

Алгоритм Луна включает следующие шаги:

  1. Удвоить каждую вторую цифру справа налево.
  2. Если удвоенное значение превышает 9, вычесть 9.
  3. Суммировать все цифры.
  4. Если остаток от деления суммы на 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, демонстрирующие различные парадигмы программирования. Хотя итеративный подход помогает в понимании, функциональные подходы, особенно расширенный, предлагают лучшую читаемость и эффективность для практического применения. Помните, что алгоритм Луна является контрольной суммой, а не полным решением для обеспечения безопасности; его следует использовать вместе с другими методами проверки.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *