Алгоритм Луна, также известный как алгоритм Mod 10, представляет собой широко используемую формулу для проверки целостности нескольких типов идентификационных строк, в первую очередь номеров кредитных карт, хотя он также используется для проверки идентификационных номеров в некоторых странах, идентификаторов IMEI и номера банковских маршрутов.
Это относительно простая формула контрольной суммы, разработанная в 1960-х годах и до сих пор широко используемая, поскольку она сохраняет свой простой вариант использования для проверки номеров кредитных карт (и других) от ошибок ввода простым и быстрым способом. Алгоритм находится в открытом доступе.
Расчет
Пример этого алгоритма проверки строки следует следующим шагам (при условии, что строка включает последнюю цифру или контрольную цифру):
- Начиная справа от числовой строки, каждая вторая цифра умножается на 2.
- Если результатом умножения является двузначное число, две цифры суммируются друг с другом, чтобы получить однозначное число.
- Все цифры в результирующей строке, включая неизмененные, суммируются вместе.
- Полученное число делится на 10: если деление не имеет остатка, то номер кредитной карты/удостоверения личности действителен.
Вот почему алгоритм Луна также называют «алгоритмом Mod 10»: целостность строки зависит от того, имеет ли результат, деленный на 10, какой-либо остаток. Этот процесс также можно использовать для вычисления контрольной цифры, т. е. цифры, которая добавляется в конец строки для ее проверки.
В следующем примере показана проверка числа 451922. Каждая вторая цифра умножается на 2, а остальные умножаются на 1, т.е. остаются неизменными. Полученные числа суммируются.
Digits 4 | 5 | 1 | 9 | 2 | 2 | Multiplier 2 | 1 | 2 | 1 | 2 | 1 | = 8 | 5 | 2 | 9 | 4 | 2 | (8 + 5 + 2 + 9 + 4 + 2 ) = 30 30 % 10 = 0
Окончательная сумма в этом случае равна 30, что делится на 10 без остатка. Это означает, что код 451922 успешно проходит проверку алгоритмом Луна.
Java-реализация
Давайте теперь реализуем это в коде. Следующий фрагмент является одним из примеров того, как этот алгоритм проверки может быть реализован в методе Java:
public static boolean validateNumber(String number){ /* Validation of user input: blank spaces are removed from the numeric string. Also, the code ensures that the input is numeric */ number = number.replaceAll(" ", ""); try{ Long.parseLong(number); } catch (NumberFormatException e){ System.out.println("Invalid input"); return false; } int sum = 0; boolean alternateDigit = false; /* Starting from the right of the string, the code loops through each digit and multiplies every second digit by 2. */ for(int i = number.length()-1; i >= 0; i--){ int digit = Integer.parseInt(number.substring(i, i+1)); if(alternateDigit){ digit *= 2; if(digit > 9){ digit = 1 + (digit % 10); } } sum += digit; alternateDigit = !alternateDigit; } return (sum % 10 == 0); }
Метод сначала выполняет некоторую проверку данных: он удаляет все пробелы, которые часто добавляются, чтобы сделать номера кредитных карт более читабельными. Это также гарантирует, что строка состоит только из цифр, без дополнительных символов, и соответствующим образом обрабатывает любой результирующий NumberFormatException
.
Затем код перебирает каждую цифру, начиная справа, для выполнения шагов, описанных в разделе выше. Каждая вторая цифра умножается на 2, и в тех случаях, когда в результате получается число больше 9, две цифры складываются вместе для вычисления однозначного числа.
На каждой итерации цикла результирующее число суммируется с переменной sum
, которая используется для отслеживания общей суммы. После завершения цикла метод возвращает true
, если sum
делится на 10.
Полный код можно найти на Github.
Ограничения
Основным вариантом использования алгоритма Луна является быстрое и эффективное выявление ошибок в числовых строках, которые могут указывать на опечатку или иное недопустимое число. Таким образом, это хорошая быстрая формула, позволяющая убедиться, например, что в номере кредитной карты нет опечаток или неуместных цифр.
Однако алгоритм не предназначен для защиты от мошенничества или неправомерных действий. Он обеспечивает только базовую проверку числовой строки и не может проверить подлинность кредитной карты или идентификационного номера. Это означает, что он не может определить, например, было ли число сгенерировано с целью обойти алгоритм путем сопоставления с его вычислением контрольной суммы.
Кроме того, он не может обеспечить более расширенную проверку, например, проверку того, связан ли номер кредитной карты с действительным банковским счетом. Должны применяться дополнительные проверки и меры безопасности для обеспечения целостности и точности любого идентификационного кода.