High quality, simple random password generator

前端 未结 27 2527
渐次进展
渐次进展 2020-12-22 17:06

I\'m interested in creating a very simple, high (cryptographic) quality random password generator. Is there a better way to do this?

import os, random, strin         


        
27条回答
  •  青春惊慌失措
    2020-12-22 17:31

    There are some problems with your implementation:

    random.seed = (os.urandom(1024))
    

    This does not seed the random number generator; it replaces the seed function with a bytestring. You need to call seed, like, random.seed(…).

    print ''.join(random.choice(chars) for i in range(length))
    

    Python's default PRNG is a Mersenne Twister, which is not a cryptographically strong PRNG, so I'm wary of using it for cryptographic purposes. The random module includes random.SystemRandom, which on at least most *nix systems, should use a CSPRNG. However,

    random.choice(chars)
    

    …is implemented as…

    def choice(self, seq):
        """Choose a random element from a non-empty sequence."""
        return seq[int(self.random() * len(seq))]  # raises IndexError if seq is empty
    

    …in Python 2. Unfortunately, self.random here is a C function, so this gets hard to see; the code smell here is that this code almost certainly doesn't choose uniformly. The code has completely changed in Python 3, and does a much better job of ensuring uniformity. The Python 3 docs for randrange note,

    Changed in version 3.2: randrange() is more sophisticated about producing equally distributed values. Formerly it used a style like int(random()*n) which could produce slightly uneven distributions.

    randrange and choice both call the same method (_randbelow) under the hood.

    In Python 3, choice is fine; in Python 2, it only comes close to a uniform distribution, but does not guarantee it. Since this is crypto, I lean on the "take no chances" side of the fence, and would like to have that guarantee.

提交回复
热议问题