Создание пароля в python

Я хотел бы генерировать несколько буквенно-цифровых паролей в python. Возможны следующие способы:

import string from random import sample, choice chars = string.letters + string.digits length = 8 ''.join(sample(chars,length)) # way 1 ''.join([choice(chars) for i in range(length)]) # way 2 

Но мне это не нравится, потому что:

  • way 1 выбраны только уникальные символы, и вы не можете генерировать пароли, где length> len (chars)
  • путь 2 у меня есть переменная неиспользованная, и я не могу найти хороший способ, как избежать этого

Итак, любые другие хорошие варианты?

PS Итак, вот мы с некоторыми испытаниями с timeit для 100000 итераций:

 ''.join(sample(chars,length)) # way 1; 2.5 seconds ''.join([choice(chars) for i in range(length)]) # way 2; 1.8 seconds (optimizer helps?) ''.join(choice(chars) for _ in range(length)) # way 3; 1.8 seconds ''.join(choice(chars) for _ in xrange(length)) # way 4; 1.73 seconds ''.join(map(lambda x: random.choice(chars), range(length))) # way 5; 2.27 seconds 

Итак, победителем является ''.join(choice(chars) for _ in xrange(length)) .

  • Проблемы с десятичными знаками и научной нотации в Python 2.6.6
  • Получить данные из Twitter с помощью Tweepy и сохранить в csv-файле
  • Как добавить дополнительные файлы на колесо?
  • Несколько параметров в флажке
  • Узел метки метки NetworkX
  • Как вы меняете Pandas DataFrame с помощью multiindex?
  • Графическая точка на прямой (номер строки) в Python
  • Правильное размещение цветной панели относительно геоосевых (картографических)
  • 6 Solutions collect form web for “Создание пароля в python”

    Вариант № 2 выглядит вполне разумным, за исключением того, что вы можете добавить несколько улучшений:

     ''.join(choice(chars) for _ in range(length)) # in py2k use xrange 

    _ является обычной переменной «Меня не волнует, что там». И вам не нужно понимать список там, выражение генератора отлично работает для str.join . Также неясно, что означает «медленный», если это единственный правильный путь.

    Python 3.6 и далее

    Вы должны использовать модуль секретов для генерации криптографически безопасных паролей, доступных начиная с Python 3.6. Адаптировано из документации:

      import secrets import string alphabet = string.ascii_letters + string.digits password = ''.join(secrets.choice(alphabet) for i in range(20)) # for a 20-character password 

    Для крипто-PRNG людей:

     def generate_temp_password(length): if not isinstance(length, int) or length < 8: raise ValueError("temp password must have positive length") chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789" from os import urandom return "".join(chars[ord(c) % len(chars)] for c in urandom(length)) 

    Обратите внимание, что для четного распределения длина строки chars должна быть интегральным делителем 128; в противном случае вам понадобится другой способ выбора из пространства.

    Я думаю, это будет трюк. random.SystemRandom использует ту же основную крипто-случайную функцию, что и os.urandom но использует знакомый random интерфейс. Эта функция не будет подвержена странным 128-байтным вещам, как в ответе Бена.

     import random import string def gen_random_string(char_set, length): if not hasattr(gen_random_string, "rng"): gen_random_string.rng = random.SystemRandom() # Create a static variable return ''.join([ gen_random_string.rng.choice(char_set) for _ in xrange(length) ]) password_charset = string.ascii_letters + string.digits gen_random_string(password_charset, 32) 

    Я написал сценарий с моими предпочтениями, которые в основном связаны с тем, чтобы избежать ошибок при расшифровке и запоминании. (Например: удалить несколько неоднозначных и не повторять символы.)

     import optparse import os import random import sys DEFAULT_CHARS = "234679ADEFGHJKLMNPRTUWabdefghijkmnpqrstuwy" 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") choices_func = choices_non_repeated if opts.repeat: choices_func = choices elif len(set(opts.chars)) < 2: op.error("must allow repetition or provide a longer character set") return "op.error shouldn't return" col = 0 for _ in xrange(opts.count): length = random.randint(opts.min, opts.max) password = "".join(choices_func(opts.chars, length)) sys.stdout.write(password) if not opts.bare: col += 1 if col == opts.cols: sys.stdout.write("\n") col = 0 else: sys.stdout.write(" ") if __name__ == "__main__": sys.exit(main(sys.argv[1:])) 

    Возможно, вы захотите использовать map вместо понимания списка:

     ''.join(map(lambda x: random.choice(chars), range(length))) 
    Python - лучший язык программирования в мире.