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

С каждым годом у современных людей увеличивается количество учетных записей, аккаунтов, доменов и т.д. Соответственно с каждым днем растет и число несанкционированных доступов, взломов, краж учетных записей. Многие сайты в связи с этим выставляют пользователям ресурсов ряд требований по созданию пароля. На сегодняшний день пароль должен состоять из таких условий:

  • не менее 12 символов, но не более — 100 символов,
  • иметь заглавные и строчные буквы,
  • содержать хотя бы несколько цифр,
  • а также хотя бы один спец. символ.

Следовательно, большинству людей такое огромное количество несвязных паролей сложно запомнить. Поэтому зачастую человек заводит один пароль на все учетные записи. Это приводит в свою очередь к снижению кибер защищенности аккаунта пользователя. Фиксировать пароли на жесткий носитель (бумагу) тоже не лучшая идея, ее можно потерять (и нужно знать где они находятся). Кроме этого нужно понимать, что на современных сайтах время от времени пароли требуется менять.   Учитывая еще одно требование к вновь создаваемому паролю, он должен отличатся более чем на 50% от предыдущего пароля. Следует учитывать так же вход происходит с разных устройств.

При существующих требованиях сложно создавать пароли. Большинство пользователей чаще используют ассоциативный способ придумывания пароля или текущую дату, что приводит к уменьшению защищённости. В таком случае можно воспользоваться уже существующим кодированием пароля, например: код Тьюринг, Хаффмана, Циклический и т.д. Соответственно этим математическим расчетами можно написать программу по созданию пароля. Человеку требуется вести ассоциативный слова, а программа сформирует для него подходящий пароль.

Код программы по формированию пароля.

import optparse
import os
import random
import sys

DEFAULT_CHARS = "Введите знакомый текст"
DEFAULT_LEN = 18

def choices(options, length, choice=random.choice):
    return (choice(options) for _ in xrange(length))

def choices_non_repeated(options, length, choice=random.choice):
  assert len(options) > 1
  last = choice(options)
  count = 0
  while count < length:
    yield last
    count += 1

    while True:
      value = choice(options)
      if value != last:
        last = value
        break

def main(args):
  op = optparse.OptionParser(add_help_option=False)
  op.add_option("--help", action="help",
    help="show help message and exit")
  op.add_option("-b", "--bare", action="store_true", default=False,
    help="print passwords without trailing newline")
  op.add_option("-c", "--chars", metavar="SET", nargs=1, default=DEFAULT_CHARS,
    help="character set to use (default: %default)")
  op.add_option("--repeat", action="store_true", default=False,
    help="allow repetition")
  op.add_option("-l", "--len", dest="max", nargs=1, type="int", default=DEFAULT_LEN,
    help="max length (default: %default)")
  op.add_option("--min", nargs=1, type="int", default=None,
    help="min length (defaults to max)")
  op.add_option("-n", "--count", nargs=1, type="int", default=None,
    help="number of passwords to generate (default: %default)")
  op.add_option("--cols", type="int", default=None,
    help="number of columns to use")
  opts, args = op.parse_args(args)
  if args:
    op.error("unknown arguments")

  if os.isatty(sys.stdin.fileno()) and (
    opts.count is None and opts.cols is None
    and not opts.bare
  ):
    opts.cols = 80 // (opts.max + 1)
    opts.count = opts.cols * 25
  else:
    if opts.count is None:
      opts.count = 1
    if opts.cols is None:
      opts.cols = 1

  if opts.bare and opts.cols != 1:
    op.error("bare output requires --cols=1")

  if opts.min == None:
    opts.min = opts.max

  if any(x < 1 for x in [opts.cols, opts.count, opts.min, opts.max]):
    op.error("values must be >= 1")