@@ -0,0 +1,1681 @@
+# encoding: utf8%0Aimport random%0A%0A%0A# Default symbols to use for passwords. Avoids visually confusing characters.%0A# ~6 bits per symbol%0ADEFAULT_PASSWORD_SYMBOLS = ('23456789',  # Removed: 0,1%0A                            'ABCDEFGHJKLMNPQRSTUVWXYZ',   # Removed: I, O%0A                            'abcdefghijkmnopqrstuvwxyz')  # Removed: l%0A%0A%0A# ~5 bits per symbol%0AEASIER_PASSWORD_SYMBOLS = ('23456789',  # Removed: 0, 1%0A                           'ABCDEFGHJKLMNPQRSTUVWXYZ')  # Removed: I, O%0A%0A%0Adef generate_password(length, symbolgroups=DEFAULT_PASSWORD_SYMBOLS):%0A    %22%22%22Generate a random password from the supplied symbol groups.%0A%0A    At least one symbol from each group will be included. Unpredictable%0A    results if length is less than the number of symbol groups.%0A%0A    Believed to be reasonably secure (with a reasonable password length!)%0A%0A    %22%22%22%0A    r = random.SystemRandom()%0A%0A    # NOTE(jerdfelt): Some password policies require at least one character%0A    # from each group of symbols, so start off with one random character%0A    # from each symbol group%0A    password = %5Br.choice(s) for s in symbolgroups%5D%0A    # If length %3C len(symbolgroups), the leading characters will only%0A    # be from the first length groups. Try our best to not be predictable%0A    # by shuffling and then truncating.%0A    r.shuffle(password)%0A    password = password%5B:length%5D%0A    length -= len(password)%0A%0A    # then fill with random characters from all symbol groups%0A    symbols = ''.join(symbolgroups)%0A    password.extend(%5Br.choice(symbols) for _i in range(length)%5D)%0A%0A    # finally shuffle to ensure first x characters aren't from a%0A    # predictable group%0A    r.shuffle(password)%0A%0A    return ''.join(password)%0A

Add the function to generate the random password.