Время прочтения: 5 мин.

В современном мире уже нельзя обойтись без использования ДПК и ПДн. Соответственно возрос интерес к этим данным и со стороны злоумышленников, которые пытаются воспользоваться ими в своих корыстных целях. Для предотвращения утечки конфиденциальных данных клиента, уделяется большое внимание к определению таких данных в обрабатываемой информации.

Так, алгоритмы проверки контрольного числа банковской карты, ИНН и СНИЛС способствует повышению качества определения ДПК и ПДн в огромном объеме анализируемой информации.

Само по себе заданное контрольное число – как правило последнее число номера равное сумме всех чисел номера или математический результат других операций с цифрами.

Указанные в документах контрольные числа, на практике, разрешают восстановить только одну ошибочно введённую цифру.

Для этого:

  1. Должно быть известно место, которое занимает цифра.

 2. Должно выполняться условие, что все оставшиеся цифры в номере верные.

Когда неизвестна позиция, где существует ошибка, нужно найти наиболее подходящий вариант решения.

Просто исправив контрольную цифру, можно получить огромную ошибку, которая не связана с точной наукой. Рассмотрим наиболее часто используемые нами алгоритмы.

При выявлении номеров платежных карт используется упрощённый алгоритм Луна:

  1. Все цифры в последовательности, которую мы проверяем, пронумеровать справа налево.

2. Нечётные – не изменяются.

3. Чётные необходимо умножить на два.

4. Если при умножении получается значение, превышающее девять, то оно заменяется однозначным числом (суммой чисел получившегося произведения).

5. Все полученные цифры складываются.

6. Если общее число делится без остатка на 10, то исходные данные верны. В данном примере номер банковской карты неверен. Номер будет верен, если последнюю цифру 4 заменить на 7.

Пример кода на языке Python:

cards_arr = ['4561 2612 1234 5467', '4561 2612 1234 5464']
for card_str in cards_arr:
    number_arr = list(card_str.replace(' ', ''))
    if len(number_arr) != 16:
        print('!Некорректный номер карты! ' + card_str)
        continue
    even_pos_sum = 0
    for num in number_arr[1::2]:
        even_pos_sum += int(num)
    odd_pos_sum = 0
    for num in number_arr[-2::-2]:
        dub_num = int(num) * 2
        if dub_num < 10:
            odd_pos_sum += dub_num
        else:
            odd_pos_sum += sum(map(int, str(dub_num)))
    if (even_pos_sum + odd_pos_sum) % 10 == 0:
        print('Номер карты корректный')
    else:
        print('!Некорректный номер карты! ' + card_str)

Алгоритм выявлении (на примере СНИЛС)

Номер не должен содержать три одинаковые цифры, следующие одна за другой подряд. Чтобы проверить, верно ли существующее контрольное значение, нужно:

  1. Все элементы Х по очереди умножить на обратный порядковый номер (1-ая цифра Х порядковый номер равен 9, для 2-й – 8 и т.п.)
  2. Суммируем получившиеся результаты.
  3. Полученная сумма сравнивается с цифрой 100.
  4. Если она меньше 100, то это значение – и есть искомое число.
  5. Если она лежит в интервале от 100 до 101, то нужное число – 00.
  6. Если она больше 101, то делим её на 101. Но, если значение не больше 300, то вычитаем из нее 101 до того момента, пока не получим цифру меньше ста. Полученное число определяется по 2-м пунктам, рассмотренных выше.

Пример.

Рассмотрим следующий номер:

Для проведения проверки нужно умножить каждое число на свой порядковый номер, а потом просуммировать их все:

Если получившееся число попало в промежуток от 101 до 300, то, следовательно, нужно произвести следующее действие 155 — 101 = 54. Контрольное значение верно.

Пример кода на языке Python:

snils_arr = ['160-722-773 54', '160-722-773 23']
for snils_str in snils_arr:
    number_arr = list(snils_str.replace('-', '')[:-3])
    if len(number_arr) != 9:
        print('!Некорректный номер СНИЛС! ' + snils_str)
        continue
    check_sum = 0
    for num, k in zip(number_arr, range(9, 0, -1)):
        check_sum += int(num) * k
    while check_sum > 101:
        check_sum %= 101
    if check_sum in (100, 101):
        check_sum = 0
    if check_sum == int(snils_str[-2:]):
        print('Номер СНИЛС корректный')
    else:
        print('!Некорректный номер СНИЛС! ' + snils_str)

Способ выявлении (на примере ИНН)

Строка состоит из 12 символов:

  1. Цифра стоящая предпоследней (11-й) совпадает с последней цифрой остатка от деления на 11 числа, являющегося суммой: k1*7 + k2*2 + k3*4 + k5*3 + k6*5 + k7*9 + k8*4 + k9*6 + k10*8, где k1, … , k10– первые десять цифр ИНН.
  2. Цифра стоящая последней (12-й) равна последней цифре остатка от деления на 11 числа, являющегося суммой: k13 + k27 + k32 + k44 + k510 + k63 + k75 + k89 + k94 + k106 + k11*8, где k1, … ,k11 – первые одиннадцать цифр ИНН.

Пример:

Реализация на языке Python:

inn_arr = ['500100732259', '500100732252']
koeffs = (3, 7, 2, 4, 10, 3, 5, 9, 4, 6, 8)
for inn_str in inn_arr:
    if len(inn_str) != 12:
        print('!Некорректный номер ИНН! ' + inn_str)
        continue
    inn_arr = list(inn_str)
    penultimate_sum = 0
    for num, k in zip(inn_arr[:10], koeffs[1:]):
        penultimate_sum += int(num) * k
    if str(penultimate_sum % 11)[-1] != inn_str[-2]:
        print('!Некорректный номер ИНН! ' + inn_str)
        continue
    last_sum = 0
    for num, k in zip(inn_arr[:11], koeffs):
        last_sum += int(num) * k
    if str(last_sum % 11)[-1] != inn_str[-1]:
        print('!Некорректный номер ИНН! ' + inn_str)
        continue
    print('Номер ИНН корректный')

Спектр применения расчета такого числа очень широк и может применяться также для регистрационных номеров предприятий, идентификационного номера транспортного средства (VIN), ИНН юр.лица, ISIN и т.д.