Filed Under (Nginx, Python) by Marcin Kuźmiński on June-23-2009

Recently i made a simple random password generator with ability to make n-length passwords with appropriate hash of this password. Especially i was interested in CRYPT to create a password for nginx passwd files. You need to make a password hashed with crypt in order to put it to any *NIX passwd file. Which has a format of username:password using the to_crypt function you can create password for these type of access files. You can use any salt for the passwords.

Heres the code fell free to use it:

'''
@author: marcink
This is a simple class for generating password from
different sets of characters

functions sha1,md5 and crypt returns a tuple of (generated_password,hashed_password,type)

'''

from hashlib import sha1, md5
import random
import crypt

class PasswordGenerator(object):

    def __init__(self, passwd = ''):

        self.ALPHABETS_NUM = r'''1234567890'''#[0]
        self.ALPHABETS_SMALL = r'''qwertyuiopasdfghjklzxcvbnm'''#[1]
        self.ALPHABETS_BIG = r'''QWERTYUIOPASDFGHJKLZXCVBNM'''#[2]
        self.ALPHABETS_SPECIAL = r'''`-=[]\;',./~!@#$%^&*()_+{}|:"<>?'''    #[3]
        self.ALPHABETS_FULL = self.ALPHABETS_BIG + self.ALPHABETS_SMALL + self.ALPHABETS_NUM + self.ALPHABETS_SPECIAL#[4]
        self.ALPHABETS_ALPHANUM = self.ALPHABETS_BIG + self.ALPHABETS_SMALL + self.ALPHABETS_NUM#[5]
        self.ALPHABETS_BIG_SMALL = self.ALPHABETS_BIG + self.ALPHABETS_SMALL
        self.ALPHABETS_ALPHANUM_BIG = self.ALPHABETS_BIG + self.ALPHABETS_NUM#[6]
        self.ALPHABETS_ALPHANUM_SMALL = self.ALPHABETS_SMALL + self.ALPHABETS_NUM#[7]
        self.passwd = passwd

    def gen_password(self, len, type):
        #''.join(seq) is 30x faster that str_password+=random.choice(type)
        self.passwd = ''.join([random.choice(type) for _ in xrange(len) ])
        return self

    def to_md5(self):
        return (self.passwd, md5(self.passwd).hexdigest(),'md5')

    def to_sha1(self):
        return (self.passwd, sha1(self.passwd).hexdigest(),'sha1')

    def to_crypt(self, salt):
        return (self.passwd, crypt.crypt(self.passwd, salt),'crypt[salt=%s]' % salt)

    def to_plain(self):
        return self.passwd

if __name__ == "__main__":
    passwd_gen = PasswordGenerator()

    #print 8-letter password containing only big and small letters of alphabet
    print passwd_gen.gen_password(8, passwd_gen.ALPHABETS_BIG_SMALL).to_plain()

    #print 8 letter password containing numbers only and return crypt hash of it
    print passwd_gen.gen_password(8, passwd_gen.ALPHABETS_NUM).to_crypt(salt = 'ab')

    # create an instance of passwordGenerator with you own password
    my_custom_password = PasswordGenerator('my_secret_password')
    print my_custom_password.to_plain()

    #print md5 of that password
    print my_custom_password.to_md5()

    '''
    sample output:
    raeBvpdd
    ('10047981', 'abOaHGCbrkA7U', 'crypt[salt=ab]')
    my_secret_password
    ('my_secret_password', '7ee416d527a2d047751c026d82dbbeef', 'md5')
    '''