Welcome, guest | Sign In | My Account | Store | Cart

Since everyone is posting one of these, I thought I'd post mine. I wrote this many years ago and use it everywhere.

Python, 52 lines
 ``` 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!

James Mills (author) 11 years, 2 months ago

An interactive version of this here:

--JamesMills / prologic

James Mills (author) 11 years, 2 months ago

An improved version of this:

--JamesMills / prologic

Grijesh Chauhan 11 years, 1 month ago

Hi James Mill,

Your code is beautiful and very good documentation.

Thanks!!

Grijesh Chauhan 11 years, 1 month ago

I have a doubt in your code.

``````>>> letters = string.letters.strip("oO")
do nothing
``````

To remove small and Capital `O` one should use translate().

``````>>> import string
>>> letters = string.letters
>>> letters
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
>>> letters.translate(None,'oO')
'abcdefghijklmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ'
``````

Am I correct?

Grijesh Chauhan 11 years, 1 month ago

The line

``````>>>   letters = string.letters.strip("oO")
``````

can be replace by

``````>>>   letters = string.letters.translate(None,'oO')
``````
James Mills (author) 11 years, 1 month ago

@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

Martin Miller 10 years, 3 months ago

The documentation for the`random`module specifically says:

Warning: The pseudo-random generators of this module should not be used for security purposes. Use`os.urandom()`or`SystemRandom`if you require a cryptographically secure pseudo-random number generator.

Which means using`random.choice()`to generate passwords might not be such a good idea.

Martin Miller 10 years, 3 months ago

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 a `random.SystemRandom` class instance as its source of pseudo-random numbers.

Just change the beginning of the script to the following:

``````import string
from time import time
from itertools import chain
# patch module to use cryptographically secure source of numbers
import random
random._inst = random.SystemRandom()
from random import seed, choice, sample
``````

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.

James Mills (author) 10 years, 3 months ago

@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?

 Created by James Mills on Thu, 21 Feb 2013 (MIT)