Алгоритм Луна: як перевірити номер картки у формі

Алгоритм Луна (Luhn algorithm) — це контрольна математична перевірка, яку часто застосовують для виявлення помилок у введеному номері платіжної картки.

Важливо: успішна перевірка Luhn не підтверджує, що картка існує, активна або може виконати платіж. Вона лише перевіряє структуру номера й контрольну цифру. Реальну перевірку виконують платіжний шлюз і банк.

Як працює алгоритм

  1. Беремо цифри номера справа наліво.
  2. Починаючи з передостанньої цифри, подвоюємо кожну другу цифру.
  3. Якщо результат більший за 9, віднімаємо 9.
  4. Додаємо змінені та незмінені цифри.
  5. Якщо сума ділиться на 10 без остачі, номер проходить перевірку.

Приклад

Для номера 4441114449324050 після обробки цифр отримуємо суму 70. Оскільки 70 % 10 = 0, номер проходить перевірку Luhn.

Перевірка у полі картки

  • Запускайте перевірку на input або після втрати фокусу через blur.
  • Перед перевіркою видаляйте пробіли й дефіси.
  • Показуйте помилку лише після введення достатньої кількості цифр, наприклад 13–19.
  • Не надсилайте номер картки на власний сервер без потреби та не зберігайте його в логах.
  • Для платежів використовуйте PCI DSS-сумісний платіжний шлюз і токенізацію.

JavaScript

function isValidCardNumber(value) {
  const num = value.replace(/\D/g, '');
  if (num.length < 13 || num.length > 19) return false;

  let sum = 0;
  let shouldDouble = false;

  for (let i = num.length - 1; i >= 0; i--) {
    let digit = Number(num[i]);
    if (shouldDouble) {
      digit *= 2;
      if (digit > 9) digit -= 9;
    }
    sum += digit;
    shouldDouble = !shouldDouble;
  }

  return sum % 10 === 0;
}

PHP

function isValidCardNumber(string $value): bool {
    $num = preg_replace('/\D/', '', $value);
    if (strlen($num) < 13 || strlen($num) > 19) {
        return false;
    }

    $sum = 0;
    $shouldDouble = false;

    for ($i = strlen($num) - 1; $i >= 0; $i--) {
        $digit = (int) $num[$i];
        if ($shouldDouble) {
            $digit *= 2;
            if ($digit > 9) $digit -= 9;
        }
        $sum += $digit;
        $shouldDouble = !$shouldDouble;
    }

    return $sum % 10 === 0;
}

Python

def is_valid_card_number(value: str) -> bool:
    num = ''.join(ch for ch in value if ch.isdigit())
    if not 13 <= len(num) <= 19:
        return False

    total = 0
    should_double = False
    for ch in reversed(num):
        digit = int(ch)
        if should_double:
            digit *= 2
            if digit > 9:
                digit -= 9
        total += digit
        should_double = not should_double

    return total % 10 == 0

Rust

pub fn is_valid_card_number(value: &str) -> bool {
    let digits: Vec<u32> = value
        .chars()
        .filter_map(|c| c.to_digit(10))
        .collect();

    if !(13..=19).contains(&digits.len()) {
        return false;
    }

    let mut sum = 0;
    let mut should_double = false;
    for mut digit in digits.iter().rev().copied() {
        if should_double {
            digit *= 2;
            if digit > 9 { digit -= 9; }
        }
        sum += digit;
        should_double = !should_double;
    }

    sum % 10 == 0
}

Висновок

Luhn — це швидкий спосіб відсіяти помилки введення на клієнті до відправлення форми. Але це лише синтаксична перевірка, а не авторизація платежу: остаточний результат завжди повертає платіжний провайдер.

Коментарі (0)

Залишити коментар

Від 25 до 1000 символів. HTML не підтримується.
Оцінка
Погано Добре