Since everyone is posting one of these, I thought I'd post mine. I wrote this many years ago and use it everywhere.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | #!/usr/bin/env python
import string
from time import time
from itertools import chain
from random import seed, choice, sample
def mkpasswd(length=8, digits=2, upper=2, lower=2):
"""Create a random password
Create a random password with the specified length and no. of
digit, upper and lower case letters.
:param length: Maximum no. of characters in the password
:type length: int
:param digits: Minimum no. of digits in the password
:type digits: int
:param upper: Minimum no. of upper case letters in the password
:type upper: int
:param lower: Minimum no. of lower case letters in the password
:type lower: int
:returns: A random password with the above constaints
:rtype: str
"""
seed(time())
lowercase = string.lowercase.translate(None, "o")
uppercase = string.uppercase.translate(None, "O")
letters = "{0:s}{1:s}".format(lowercase, uppercase)
password = list(
chain(
(choice(uppercase) for _ in range(upper)),
(choice(lowercase) for _ in range(lower)),
(choice(string.digits) for _ in range(digits)),
(choice(letters) for _ in range((length - digits - upper - lower)))
)
)
return "".join(sample(password, len(password)))
print mkpasswd()
print mkpasswd(12)
print mkpasswd(digits=3)
print mkpasswd(12, upper=4)
|
ChangeLog:
- Fixed missing import of
sample(...)
- Fixed several issues with the sets of lower and upper case letters. Thanks for the comments!
An interactive version of this here:
http://codepad.org/WkWX1FUg
--JamesMills / prologic
An improved version of this:
http://codepad.org/BRf7it2s
--JamesMills / prologic
Hi James Mill,
Your code is beautiful and very good documentation.
Thanks!!
I have a doubt in your code.
In your code line:
To remove small and Capital
O
one should use translate().Am I correct?
The line
can be replace by
@Grijesh: Thank you for your comments. I have fixed the sets of letters :)
NB: This only works on Python 2.6 and 2.7 now.
--JamesMills / prologic
The documentation for the
random
module specifically says:Which means using
random.choice()
to generate passwords might not be such a good idea.To follow-up on my previous comment/criticism, from looking at the current (v2.7.6 and v3.3.3) source code for the
random
module, fortunately there appears to be a simple way to make the methods in it use arandom.SystemRandom
class instance as its source of pseudo-random numbers.Just change the beginning of the script to the following:
Note that the documentation says that
SystemRandom
isn't available on all systems, so doing this makes the script slightly less portable, but it will fail in that case, rather than generate less secure passwords.@Martin Miller: Thanks! I'll do that :) TBH I don't know a terrible lot about the internals of random nor much about cryptography in general (as much as the next developer I guess).
It seems to me though; that it isn't completely necessary to have a source of cryptographically secure random numbers or a true random number generator to generator good passwords? Maybe that's a bad assumption as hackers with similar or identical hardware could potentially generate a dictionary of the same passwords?