unit Creditc;
{*****************************************************************************
Модуль Delphi для проверки номера кредитной карты
Версия: 1.1
Дата: Декабрь 20, 1996
Данный модуль создан на основе алгоритма ccard автора Peter Miller.
Автор не против бесплатного использования, но резервирует все права
на данный алгоритм.
авторское право 1996 Shawn Wilson Harvell ( shawn@inet.net )
применение:
Внесите данный модуль в список uses любого модуля, которому
необходим доступ к функции проверки кредитной карты.
IsValidCreditCardNumber( CardNumber, ReturnMessage ) returns Boolean
например, используйте это для уведомления пользователя о недействительности карты.
CardNumber - строка, содержащая номер карты, которую необходимо проверить
ReturnMessage - строка, с помощью которой функция может возвратить любое сообщение
( при этом старое содержимое строки стирается )
возвращает true если номер карточки верен, false - в противном случае.
во входных параметрах функции допускаются тире и пробелы,
если же возможно присутствие других символов, вы можете их удалить.
Функция RemoveChar довольно легко позаботится об этом, просто
передайте ей входную строку и символ, который вы хотите удалить.
Пользователь может свободно изменять код модуля для собственных целей,
но в случае его распространения он должен сообщить пользователям
обо всех внесенных изменениях.
Используйте модуль на свой страх и риск, поскольку он свободен от явных
и неявных гарантий. Ответственность за какой-либо ущерб, причиненный
данным модулем лежит на его пользователе.
На момент написания модуля он устойчиво работал под Delphi версий 1 и 2,
для Turbo Pascal необходимо внести некоторые несложные исправления (главным
образом из-за различия реализации функций в модуле SysUtils).
Если вы нашли этот модуль полезным, имеете какие-то пожелания или предложения,
отправьте автору письмо по адресу электронной почты shawn@inet.net
История изменений
версия 1.1 -- Декабрь 20, 1996
исправлена ошибка с Discover card: соответственно увеличина длина маски "database"
версия 1.0 -- Октябрь 26, 1996
первый выпуск
*****************************************************************************}interfaceuses SysUtils;
function IsValidCreditCardNumber(CardNumber: string; var MessageText: string):
Boolean;
implementationconst
CardPrefixes: array[1..19] ofstring =
('2014', '2149', '300', '301', '302',
'303', '304', '305', '34', '36', '37',
'38', '4', '51', '52', '53', '54', '55', '6011');
CardTypes: array[1..19] ofstring =
('enRoute',
'enRoute',
'Diner Club/Carte Blanche',
'Diner Club/Carte Blanche',
'Diner Club/Carte Blanche',
'Diner Club/Carte Blanche',
'Diner Club/Carte Blanche',
'Diner Club/Carte Blanche',
'American Express',
'Diner Club/Carte Blanche',
'American Express',
'Diner Club/Carte Blanche',
'Visa',
'MasterCard',
'MasterCard',
'MasterCard',
'MasterCard',
'MasterCard',
'Discover');
function RemoveChar(const Input: string; DeletedChar: Char): string;
var
Index: Word; { переменная счетчика }begin{ данная функция удаляет все вхождения указанного символа из переданной ей }{ строки }
Result := Input;
for Index := Length(Result) downto 1 doif Result[Index] = DeletedChar then
Delete(Result, Index, 1);
end;
function ShiftMask(Input: Integer): Integer;
begin{ простая оболочка для функции сдвига битов числа }
result := (1 shl (Input - 12));
end;
function ConfirmChecksum(CardNumber: string): Boolean;
var
CheckSum: Integer; { Содержит значение операции }
Flag: Boolean; { флаг готовности }
Counter: Integer; { индекс счетчика }
PartNumber: string; { используется для извлечения каждой цифры числа}
Number: Integer; { исп-ся для преобразования каждой цифры в число}begin{**************************************************************************
Это, вероятно, самая запутанный код, который вы когда-либо видели, я и сам
запутался, когда работал над ним. Основное, что делает данная функция -
извлекает каждую цифру из номера карты для использования в формуле проверки
контрольной суммы, устанавливаемую компаниями. Алгоритм производит выборку,
начиная от последней цифры и заканчивая первой.
**************************************************************************}{ получаем стартовое значение счетчика }
Counter := Length(CardNumber);
CheckSum := 0;
PartNumber := '';
Number := 0;
Flag := false;
while (Counter >= 1) dobegin{ получаем текущую цифру }
PartNumber := Copy(CardNumber, Counter, 1);
Number := StrToInt(PartNumber); { преобразуем в число }if (Flag) then{ только каждую вторую цифру }begin
Number := Number * 2;
if (Number >= 10) then
Number := Number - 9;
end;
CheckSum := CheckSum + Number;
Flag := not (Flag);
Counter := Counter - 1;
end;
result := ((CheckSum mod 10) = 0);
end;
function GetMask(CardName: string): Integer;
begin{ значение по умолчанию }
result := 0;
if (CardName = 'MasterCard') then
result := ShiftMask(16);
if (CardName = 'Visa') then
result := (ShiftMask(13) or ShiftMask(16));
if (CardName = 'American Express') then
result := ShiftMask(15);
if (CardName = 'Diner Club/Carte Blanche') then
result := ShiftMask(14);
if (CardName = 'Discover') then
result := ShiftMask(16);
end;
function IsValidCreditCardNumber(CardNumber: string; var MessageText: string):
Boolean;
var
StrippedNumber: string;
{ используется для хранения числа без дополнительных символов }
Index: Integer; { универсальный счетчик для циклов и т.п. }
TheMask: Integer;
{ число, которое мы будем использовать для маски }
FoundIt: Boolean;
{ используется для индикации, когда что-либо найдено }
CardName: string;
{ хранит имя типа карты }
PerformChecksum: Boolean;
{ тип enRoute карты если контрольная сумма не сошлась }begin{ сначала избавимся от пробелов и тире }
StrippedNumber := RemoveChar(CardNumber, ' ');
StrippedNumber := RemoveChar(StrippedNumber, '-');
{ если строка была нулевой длины, то тоже OK }if (StrippedNumber = '') thenbegin
result := true;
exit;
end;
{ инициализация возвращаемых переменных }
MessageText := '';
result := true;
{ устанавливаем нашу переменную-флаг }
FoundIt := false;
{ проверка правильности введенных символов в номере карты }for Index := 1 to Length(StrippedNumber) dobegincase StrippedNumber[Index] of
'0'..'9': FoundIt := FoundIt; { другими словами не op }else
MessageText := 'Неверный введенный символ';
result := false;
exit;
end;
end;
{ теперь давайте определим тип используемой карты }for Index := 1 to 19 dobeginif (Pos(CardPrefixes[Index], StrippedNumber) = 1) thenbegin{ мы обнаружили правильный тип }
FoundIt := true;
CardName := CardTypes[Index];
TheMask := GetMask(CardName);
end;
end;
{ если тип карты не определен, указываем на это }if (not FoundIt) thenbegin
CardName := 'Unknown Card Type';
TheMask := 0;
MessageText := 'Неизвестный тип карты ';
result := false;
exit;
end;
{ проверка длины }if ((Length(StrippedNumber) > 28) and result) thenbegin
MessageText := 'Номер слишком большой ';
result := false;
exit;
end;
{ проверка длины }if ((Length(StrippedNumber) < 12) or
((shiftmask(length(strippednumber)) and themask) = 0)) thenbegin
messagetext := 'неверная длина числа';
result := false;
exit;
end;
{ проверяем вычисление контрольной суммы }if (cardname = 'enroute') then
performchecksum := falseelse
performchecksum := true;
if (performchecksum and (not confirmchecksum(strippednumber))) thenbegin
messagetext := 'неверная контрольная сумма';
result := false;
exit;
end;
{ если результат равен true, тогда все ok }if (result) then
messagetext := 'номер верен: тип карты: ' + cardname;
{ если строка была нулевой длины, то тоже OK }if (strippednumber = '') then
result := true;
end;
end.
Эта часть кода на языке Delphi называется Creditc и содержит функцию IsValidCreditCardNumber, которая проверяет является ли номер кредитной карты валидным или нет.
Константы
Первый раздел определяет два константных массива: CardPrefixes и CardTypes. Эти массивы содержат строки, представляющие различные префиксы и типы кредитных карт соответственно.
Функции
1. RemoveChar: эта функция удаляет все вхождения указанного символа из входной строки.
2. ShiftMask: эта функция сдвигает биты целого числа, чтобы создать маску для конкретного типа кредитной карты.
3. ConfirmChecksum: эта функция рассчитывает чексум номера кредитной карты по определенной алгоритму (не показанному).
4. GetMask: эта функция возвращает маску для конкретного типа кредитной карты на основе ее имени.
IsValidCreditCardNumber
Это основная функция, которая проверяет является ли номер кредитной карты валидным или нет. Она выполняет следующие шаги:
1. Удаляет из входной строки пробелы и тире.
2. Проверяет, если полученная строка пуста; если так, возвращает true.
3. Инициализирует переменные для отслеживания результата, текст сообщения и флаговых значений.
4. Перебирает каждый символ в входной строке:
* Если найден нецифровой символ, устанавливает результат в false и выходит.
5. Проверяет, если тип карты (на основе префиксов) известен; если нет, устанавливает результат в false и выходит.
6. Рассчитывает длину очищенного номера; если она слишком длинная или слишком короткая, устанавливает результат в false и выходит.
7. Если тип карты требует расчета чексума, выполняет этот шаг:
+ Если чексум не совпадает, устанавливает результат в false и выходит.
8. Наконец, возвращает результат (true или false) вместе с текстом сообщения, указывающим на исход.
Замечания
Код использует комбинацию алгоритмов и гетеристик для проверки номеров кредитных карт.
*worth noting, что это реализация довольно старая (от 1996 года!) и может не покрывать все современные типы или форматы кредитных карт. Вам может потребоваться обновление или модификация кода для соответствия вашему конкретному использованию.
В целом функция IsValidCreditCardNumber - это комплексная и сложная реализация логики проверки номеров кредитных карт, но ее возраст и ограниченное покрытие могут сделать ее менее подходящей для современных приложений.
Проверка кредитной карты - модуль для Delphi, предназначенный для проверки номера кредитной карты на соответствие алгоритму ccard автора Peter Miller.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.