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) 9 years, 3 months ago

An interactive version of this here:

--JamesMills / prologic

James Mills (author) 9 years, 3 months ago

An improved version of this:

--JamesMills / prologic

Grijesh Chauhan 9 years, 3 months ago

Hi James Mill,

Your code is beautiful and very good documentation.

Thanks!!

Grijesh Chauhan 9 years, 3 months 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 9 years, 3 months ago

The line

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

can be replace by

``````>>>   letters = string.letters.translate(None,'oO')
``````
James Mills (author) 9 years, 3 months 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 8 years, 4 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 8 years, 4 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) 8 years, 4 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)