Python и проверка валидности банковской карты

Недавно я проходил квест на admin2012.ru .

Один из вопросов заключался в том, что необходимо восстановить недостающие цифры банковской карты.
В наличие были лишь первые и последние 4 цифры: 5213 XXXX XXXX 5213 (X — неизвестно) и хэш-значение (sha256) данного номера «edc2252293050545c2f51ca8426894b6ea3741bdd8a31bab88f875e91b06e4b8».

Решать проблему я принялся «в лоб»:

  1. Открыл Vim и начал писать скрипт на python. Начинался он с следующих строк:
    #!/usr/bin/env python
    import hashlib
    import sys
    realdigest = 'edc2252293050545c2f51ca8426894b6ea3741bdd8a31bab88f875e91b06e4b8'
  2. Добавил один while цикл
    range_min = 0
    range_max = 99999999
    while range_min <= range_max:
      code = '5213%08d3452'%range_min
  3. И начал сравнивать значение хэш-функции (sha256) сгеденированного значения со значением из условия задачи
    (необходимо добавить в конец while цикла)
    hexdigest = hashlib.sha256(code).hexdigest()
    if hexdigest==realdigest:
      print 'Bingo:\t'+hexdigest+'\t'+code
      sys.exit()
    range_min+=1

А как же алгоритм формирования цифр на банковской карте

Первый запуск показал, что я погарячился и скрипт выполнялся ОООЧЕНЬ медленно )
Решил прочитать про закономерность формирования номеров банковских карт и нашел. Последняя цифра является «контрольной суммой», которая получается после ряда операций над остальными цифрами (Сам алгоритм рассмотрим в другой статье).

Покопавшись по инету я нашел алгоритм проверки валидности карты для python.

Добавил код функции проверки валидности в скрипт

import re
def validate_cc(s):
 
  # уберем все лишнее из строки и оставляем только цифры
  s = re.sub("[^0-9]", "", str(s))
  # для моей задачи есть лишние регулярные выражения
  # но я сохраню авторский код
  regexps = [
 
            "^4\d{15}$",
            "^5[1-5]\d{14}$",
            "^3[4,7]\d{13}$",
            "^3[0,6,8]\d{12}$",
            "^6011\d{12}$",
            ]
 
  if not any(re.match(r, s) for r in regexps):
    return False
 
  chksum = 0
  x = len(s) % 2
 
  for i, c in enumerate(s):
    j = int(c)
    if i % 2 == x:
      k = j*2
      if k >= 10:
        k -= 9
      chksum += k
    else:
      chksum += j
 
  return chksum % 10 == 0

Осталось вставить проверку на валидность сгенерированного кода перед вычислением хэш-значения. Вместо 3го пункта необходимо вставить следующий код.

if validate_cc(code):
  hexdigest = hashlib.sha256(code).hexdigest()
  print code+'\t'+hexdigest
  if hexdigest==realdigest:
    print 'Bingo:\t'+hexdigest+'\t'+code
    sys.exit()
range_min+=1

Вот и все.

Полный текст скрипта на python для проверки валидности банковской платежной карты

#!/usr/bin/env python
import hashlib
import sys
import re
def validate_cc(s):
    s = re.sub("[^0-9]", "", str(s))
    regexps = [
            "^4\d{15}$",
            "^5[1-5]\d{14}$",
            "^3[4,7]\d{13}$",
            "^3[0,6,8]\d{12}$",
            "^6011\d{12}$",
            ]
 
    if not any(re.match(r, s) for r in regexps):
        return False
 
    chksum = 0
    x = len(s) % 2
 
    for i, c in enumerate(s):
        j = int(c)
        if i % 2 == x:
            k = j*2
            if k >= 10:
                k -= 9
            chksum += k
        else:
            chksum += j
 
    return chksum % 10 == 0
 
realdigest = 'edc2252293050545c2f51ca8426894b6ea3741bdd8a31bab88f875e91b06e4b8'
range_min = 0
range_max = 99999999
 
while range_min <= range_max:
  code = '5213%08d3452'%range_min
  if validate_cc(code):
    hexdigest = hashlib.sha256(code).hexdigest()
    print code+'\t'+hexdigest
    if hexdigest==realdigest:
      print 'Bingo:\t'+hexdigest+'\t'+code
      sys.exit()
  range_min+=1
Инетересно, а какой результат получился у Вас?

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

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