代码之家  ›  专栏  ›  技术社区  ›  HardQuestions

在python中生成密码

  •  40
  • HardQuestions  · 技术社区  · 15 年前

    我喜欢用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
    

    但我不喜欢两者,因为:

    • 1路 只有选定的唯一字符,并且不能在长度为>len(字符)的情况下生成密码。
    • 2路 我们有 i 变量未使用,我无法找到避免这种情况的好方法

    那么,还有其他好的选择吗?

    P.S.所以我们来做一些测试 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)) .

    7 回复  |  直到 15 年前
        1
  •  79
  •   ibodi    7 年前

    secrets module

    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
    
        2
  •  32
  •   Ben Mosher    9 年前

    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

        3
  •  13
  •   Eli Korvigo    7 年前

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

    _ str.join

        4
  •  5
  •   Eli Korvigo    7 年前

    random.SystemRandom os.urandom random

    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)
    
        5
  •  4
  •   gardarh    7 年前

    import os, math, string, struct
    
    def generate_password(pass_len):
        symbols = string.printable.strip()
        return ''.join([symbols[x * len(symbols) / 256] for x in struct.unpack('%dB' % (pass_len,), os.urandom(pass_len))])
    

        6
  •  -4
  •   Roger Pate    15 年前

    script

    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:]))
    
        7
  •  -4
  •   Sergey Stolyarov    15 年前

    map

    ''.join(map(lambda x: random.choice(chars), range(length)))