#!/usr/bin/env python """ Generate a random password with controllable characteristics. Mark Fickett [ naib.webhop.org ] 2008 Dec 15 """ import string import random import optparse def GeneratePassword( length=8, exclude='', lowercaseWeight=1.0, uppercaseWeight=1.0, digitWeight=1.0, punctuationWeight=1.0) : charInfo = [ (lowercaseWeight, string.lowercase), (uppercaseWeight, string.uppercase), (digitWeight, string.digits), (punctuationWeight, string.punctuation), ] choices = [] excludeSet = set(exclude) totalWeight = 0 for weight, charString in charInfo: charSet = set(charString) charSet -= excludeSet sectionWeight = max(0, weight)*len(charSet) if sectionWeight == 0: continue choices.append( (sectionWeight, list(charSet)) ) totalWeight += sectionWeight password = '' if totalWeight == 0: return password for n in xrange(0, length): i = random.random()*totalWeight for wt, charList in choices: if i < wt: index = int((i/wt)*len(charList)) password += charList[index] break else: i -= wt return password def main(): parser = optparse.OptionParser() parser.add_option("-n", "--numchars", dest="numchars", default=8, help="number of characters in the desired password") parser.add_option("-e", "--exclude", dest="exclude", default='', help="exclude characters found in EXCLUDESTRING", metavar="EXCLUDESTRING") parser.add_option("-l", "--lowercase-weight", dest="lower", default=1, help="relative weighting for characters in the lowercase set") parser.add_option("-u", "--uppercase-weight", dest="upper", default=1, help="relative weighting for characters in the uppercase set") parser.add_option("-d", "--digit-weight", dest="digit", default=1, help="relative weighting for characters in the digit set") parser.add_option("-p", "--punctuation-weight", dest="punct", default=1, help="relative weighting for characters in the punctuation set") options, args = parser.parse_args() print GeneratePassword( length = int(options.numchars), exclude = str(options.exclude), lowercaseWeight = float(options.lower), uppercaseWeight = float(options.upper), digitWeight = float(options.digit), punctuationWeight = float(options.punct)) if __name__ == "__main__": main()