High quality, simple random password generator

前端 未结 27 2357
渐次进展
渐次进展 2020-12-22 17:06

I\'m interested in creating a very simple, high (cryptographic) quality random password generator. Is there a better way to do this?

import os, random, strin         


        
相关标签:
27条回答
  • 2020-12-22 17:20

    This is a simple small program addressed to people whome can't figure out a secure passwords for there own public accounts.

    Just run the program on a command console and pass in a bunch of letters that seems familiar to you, and it will generate a sequence of symbols based on what you've inserted.

    of course, the program does not support multiple sequences generation.

    You can download the code from my github pull: https://github.com/abdechahidely/python_password_generator

    from string import ascii_lowercase, ascii_uppercase, digits, punctuation
    from random import randint, choice, shuffle
    from math   import ceil
    from re     import finditer
    
    lower_cases  = ascii_lowercase
    upper_cases  = ascii_uppercase
    lower_upper  = dict(zip(lower_cases, upper_cases))
    upper_lower  = dict(zip(upper_cases, lower_cases))
    punctuations = '#$%&@!?.'
    space        = ' '
    
    class PunctOrDigit():
    
        def __init__(self, number_of_punctuations, number_of_digits):
            self.puncts = number_of_punctuations
            self.digits = number_of_digits
            self.dupl_puncts = self.puncts
            self.dupl_digits = self.digits
    
        def PorD(self):
            symbol_type = choice('pd')
            if symbol_type == 'p':
                if self.puncts == 0:
                    return 'd'
                else:
                    self.puncts -= 1
                    return symbol_type
            if symbol_type == 'd':
                if self.digits == 0:
                    return 'p'
                else:
                    self.digits -= 1
                    return symbol_type
    
        def reset(self):
            self.puncts = self.dupl_puncts
            self.digits = self.dupl_digits
    
    def is_empty(text):
        for symbol in text:
            if symbol != space:
                return False
        return True
    
    def contain_unauthorized_symbols(text):
        for symbol in text:
            if symbol in punctuation or symbol in digits:
                return True
        return False
    
    def user_input():
        user_input = input('-- Sentence to transform: ')
        while is_empty(user_input) or len(user_input) < 8 or contain_unauthorized_symbols(user_input):
            user_input = input('-- Sentence to transform: ')
        return user_input
    
    def number_of_punctuations(text):
        return ceil(len(text) / 2) - 3
    
    def number_of_digits(text):
        return ceil(len(text) / 2) - 2
    
    def total_symbols(text):
        return (number_of_digits(text) + number_of_punctuations(text), 
                number_of_punctuations(text),
                number_of_digits(text))
    
    def positions_to_change(text):
        pos_objct = PunctOrDigit(number_of_punctuations(text), number_of_digits(text))
        positions = {}
        while len(positions) < total_symbols(text)[0]:
            i = randint(0,len(text)-1)
            while i in positions:
                i = randint(0,len(text)-1)
            positions[i] = pos_objct.PorD()
        pos_objct.reset()
        return positions
    
    def random_switch(letter):
        if letter in lower_cases:
            switch_or_pass = choice('sp')
            if switch_or_pass == 's': return lower_upper[letter]
            else:                     return letter
        if letter in upper_cases:
            switch_or_pass = choice('sp')
            if switch_or_pass == 's': return upper_lower[letter]
            else:                     return letter
    
    def repeated(text):
        reps = {}
        for letter in set(list(text)):
            indexs = [w.start() for w in finditer(letter, text)]
            if letter != ' ':
                if len(indexs) != 1:
                    reps[letter] = indexs
        return reps
    
    def not_repeated(text):
        reps = {}
        for letter in set(list(text)):
            indexs = [w.start() for w in finditer(letter, text)]
            if letter != ' ':
                if len(indexs) == 1:
                    reps[letter] = indexs
        return reps
    
    def generator(text, positions_to_change):
        rep     = repeated(text)
        not_rep = not_repeated(text)
        text    = list(text)
    
        for x in text:
            x_pos = text.index(x)
            if x not in positions_to_change:
                text[x_pos] = random_switch(x)
    
        for x in rep:
            for pos in rep[x]:
                if pos in positions_to_change:
                    if positions_to_change[pos] == 'p':
                        shuffle(list(punctuations))
                        text[pos] = choice(punctuations)
                    if positions_to_change[pos] == 'd':
                        shuffle(list(digits))
                        text[pos] = choice(digits)
        for x in not_rep:
            for pos in not_rep[x]:
                if pos in positions_to_change:
                    if positions_to_change[pos] == 'p':
                        shuffle(list(punctuations))
                        text[pos] = choice(punctuations)
                    if positions_to_change[pos] == 'd':
                        shuffle(list(digits))
                        text[pos] = choice(digits)
    
        text = ''.join(text)
        return text
    
    if __name__ == '__main__':
        x = user_input()
        print(generator(x, positions_to_change(x)))
    
    0 讨论(0)
  • 2020-12-22 17:21
    import random
    
    
    r = random.SystemRandom()
    
    
    def generate_password(words, top=2000, k=4, numbers=None, characters=None,
                          first_upper=True):
        """Return a random password based on a sorted word list."""
        elements = r.sample(words[:top], k)
    
        if numbers:
            elements.insert(r.randint(1, len(elements)), r.choice(numbers))
        if characters:
            elements.insert(r.randint(1, len(elements)), r.choice(characters))
        if first_upper:
            elements[0] = elements[0].title()
    
        return ''.join(elements)
    
    
    if __name__ == '__main__':
        with open('./google-10000-english-usa.txt') as f:
            words = [w.strip() for w in f]
        print(generate_password(words, numbers='0123456789', characters='!@#$%'))
    
    • Generates passwords that you can remember
    • Uses os.urandom()
    • Handles real-world rules like adding numbers, uppercase, characters.

    Sure it can be improved, but this is what I use.

    0 讨论(0)
  • 2020-12-22 17:21

    Built my own CLI answer to the topic at hand (full source code at the following URL):

    http://0netenv.blogspot.com/2016/08/password-generator-with-argparse.html

    Wrote a password generator using argparse. Hope this helps someone (either building a password generator or using argparse)!

    Either way, it was fun to build!

    $ ./pwgen.py -h
    usage: pwgen.py [-h] [-c COUNT] [-a] [-l] [-n] [-s] [-u] [-p]
    
     Create a random password
     Special characters, numbers, UPPERCASE -"Oscar",
     and lowercase -"lima" to avoid confusion.
     Default options (no arguments): -c 16 -a
                    Enjoy! --0NetEnv@gmail.com
    
    optional arguments:
      -h, --help            show this help message and exit
      -c COUNT, --count COUNT
                            password length
      -a, --all             same as -l -n -s -u
      -l, --lower           include lowercase characters
      -n, --number          include 0-9
      -s, --special         include special characters
      -u, --upper           include uppercase characters
      -p, --license         print license and exit
    

    Here's the code:

    #!/usr/bin/env python2
    # -*- coding: utf-8 -*-
    
    license = """
    #  pwgen -- the pseudo-random password generator 
    #
    #  This software is distributed under the MIT license.
    #    
    #  The MIT License (MIT)
    #
    #  Copyright (c) 2016 0NetEnv 0netenv@gmail.com
    #  Permission is hereby granted, free of charge, to any 
    #  person obtaining a copy of this software and associated 
    #  documentation files (the "Software"), to deal in the 
    #  Software without restriction, including without 
    #  limitation the rights to use, copy, modify, merge, 
    #  publish, distribute, sublicense, and/or sell copies 
    #  of the Software, and to permit persons to whom the 
    #  Software is furnished to do so, subject to the following 
    #  conditions:
    #
    #  The above copyright notice and this permission notice 
    #  shall be included in all copies or substantial portions 
    #  of the Software.
    #
    #  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 
    #  ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
    #  TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 
    #  PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 
    #  SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 
    #  CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 
    #  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 
    #  IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
    #  DEALINGS IN THE SOFTWARE.
    #  
    #  NOTE:
    #  This software was tested on Slackware 14.2, Raspbian, & 
    #  Mac OS X 10.11
    #
    """
    
    import string
    import random
    import sys
    # first time using argparse library
    import argparse
    # wanted to change the formatting of the help menu a little bit, so used RawTextHelpFormatter directly
    from argparse import RawTextHelpFormatter
    
    typo = ''
    c = 16
    counter = 0
    line = '-' * 40
    
    # CREATE FUNCTION for PWGEN
    def pwgen(z, t):
        # EMPTY SET OF CHARACTERS
        charsset = ''
        # UPPERCASE -"O"
        U = 'ABCDEFGHIJKLMNPQRSTUVWXYZ'
        # lowercase -"l"
        L = 'abcdefghijkmnopqrstuvwxyz'
        N = '0123456789'
        S = '!@#$%^&*?<>'
    
        # make sure we're using an integer, not a char/string
        z = int(z)
        for type in t:
            if 'u' in t:
                charsset = charsset + U
            if 'l' in t:
                charsset = charsset + L
            if 'n' in t:
                charsset = charsset + N
            if 's' in t:
                charsset = charsset + S
            if 'a' == t:
                charsset = charsset + U + L + N + S
    
        return ''.join(random.choice(charsset) for _ in range(0, int(z)))
    
    # GET ARGUMENTS using ARGPARSE
    parser = argparse.ArgumentParser(description='\n Create a random password\n\
     Special characters, numbers, UPPERCASE -"Oscar",\n\
     and lowercase -"lima" to avoid confusion.\n\
     Default options (no arguments): -c 16 -a\n\
     \t\tEnjoy! --0NetEnv@gmail.com', formatter_class=argparse.RawTextHelpFormatter)
    parser.add_argument("-c", "--count", dest="count", action="store", help="password length")
    parser.add_argument("-a", "--all", help="same as -l -n -s -u", action="store_true")
    parser.add_argument("-l", "--lower", help="include lowercase characters", action="store_true")
    parser.add_argument("-n", "--number", help="include 0-9", action="store_true")
    parser.add_argument("-s", "--special", help="include special characters", action="store_true")
    parser.add_argument("-u", "--upper", help="include uppercase characters", action="store_true")
    parser.add_argument("-p", "--license", help="print license and exit", action="store_true")
    
    # COLLECT ARGPARSE RESULTS
    results = args = parser.parse_args()
    
    # CHECK RESULTS
    # Check that a length was given.
    # If not, gripe and exit.
    if args.count == '0':
        print ("Input error:\nCannot create a zero length password.\nExiting")
        exit (0)
    # check character results and add to counter if 
    # selection is made.
    if args.lower:
        typo = typo + 'l'
        counter = counter + 1
        #print "lower"
    if args.number:
        typo = typo + 'n'
        counter = counter + 1
        #print "number"
    if args.special:
        typo = typo + 's'
        counter = counter + 1
        #print "special"
    if args.upper:
        typo = typo + 'u'
        counter = counter + 1
        #print "upper"
    if args.all:
        typo = 'a'
        counter = counter + 1
        #print "all"
    if args.license:
        print (license)
        exit (1)
    
    # CHECK COUNTER
    # Check our counter and see if we used any command line 
    # options. We don't want to error out.
    # try it gracefully. If no arguments are given, 
    # use defaults and tell the user.
    # args.count comes from argparse and by default requires
    # an input to '-c'. We want to get around that for the 
    # sake of convenience.
    # Without further adieu, here's our if statement:
    if args.count:
        if counter == 0:
            typo = 'a'
            print ("defaulting to '--all'")
        print (line)
        print (pwgen(results.count,typo))
    else:
        if counter == 0:
            typo = 'a'
            print ("defaulting to '--count 16 --all'")
        print (line)
        print (pwgen(c,typo))
    print (line)
    #print typo
    
    0 讨论(0)
  • 2020-12-22 17:22

    FYI for anyone running across this question in the year 2020+. Python 3.6+ has a secrets module specifically for this purpose:

    import secrets
    
    password_length = 13
    print(secrets.token_urlsafe(password_length))
    
    0 讨论(0)
  • 2020-12-22 17:29
    """
    This code below in any shape or form is owned by A.S Gallery 
    
    This code is the asnwer for Password Generator quiz - CodeHs 
    This code works 100%
    Have fun exploring !!!
    
    """
    
    # Imports 
    import random
    import time
    print "Hi !!!"
    password_output = "this is your new password : "
    ask_name = input("Enter your Name : ")
    greetings_name = "Hi "+ str(ask_name) + "!!! "
    print greetings_name
    print "Now we will make your new password using the ULTIMATE password generator !!!"
    time.sleep(8)
    print "Our password generator will give you multiple choices, you can choose any password generator you want !!! "
    time.sleep(8)
    print "You can choose if you want a strong password or a weak password !! (strong recommended) "
    time.sleep(8)
    print "You can also make your own password, to make your own password type own !!! "
    time.sleep(8)
    print "If you want to choose strong type strong, if weak then type weak !!! "
    time.sleep(8)
    
    
    
    
    # Example:
    # Returns random number within and including 0 and 10.
    def strong_password():
        user_input = int(input("Enter a number : "))
        print type(user_input)
        time.sleep(3)
        # calculate_input = user_input * user_input
        calculate_types = input("Do you want to add, multiply or mod the numbers : ")
        time.sleep(3)
        if calculate_types == "add":
            calculate_input = user_input + user_input
        elif calculate_types == "multiply" :
            calculate_input = user_input * user_input
        elif calculate_types == "mod":
            calculate_input = user_input & user_input 
        else:
            print "Check your spelling and try again :( "
    
        # Random element in a string
        time.sleep(4)
        want_symbols = input("Do you want symbols ?(Y/N) : ")
        time.sleep(4)
        random_element = random.choice('abcdefg345')
        if want_symbols == "Y":
            random_element2 = random.choice('@#()@*($*(@)(*^()*()(#$)*@#)*((@*()@*#)(*)@*($*(%#*)#(*@@_!_()(')
        elif want_symbols == "N":
            random_element2 = random.choice('29371294203712492703740182903820498201381204AKSJFKSHEHJKFJAODL')
        random_element3 = random.choice('abcdefghiiasudasdjsiasdhwudagsjdgaskdjsafgjasj')
        random_element4 = random.choice('abcdefghijsdhjaskdhkasjdhakdjhaskdasjdhakjsd')
        random_element5 = random.choice('abcdefghijsdhsakjdhsajdldasjdasdjasldas')
        random_elements6 = random.choice('129389230928308290382109830293943827492347')
        random_elements7 = random.choice('2473285473q9mdnuwyr8KSDJKDSJKL932uc3487389473289479h3289wjdi94802w')
        random_elements8 = random.choice('AKDJKAJDKJIKJDUIFHSJHUFRUDIJFDKLDJKDJLJFKLJKLDJLDJKLDJLDJLSKJDKLJDLJDKSLJD')
    
    
        time.sleep(8)
    
        print str(ask_name) + " " + str(password_output) + str(calculate_input) + str(random_element) + str(random_element2) + str(random_element3) + str(random_element4) + str(random_element5) + str(random_elements6) + str(random_elements7) + str(random_elements8)
    
    def weak_password():
        user_input = int(input("Enter a number : "))
        print type(user_input)
        time.sleep(3)
        # calculate_input = user_input * user_input
        calculate_types = input("Do you want to add, multiply or mod the numbers : ")
        time.sleep(3)
        if calculate_types == "add":
            calculate_input = user_input + user_input
        elif calculate_types == "multiply" :
            calculate_input = user_input * user_input
        elif calculate_types == "mod":
            calculate_input = user_input & user_input 
        else:
            time.sleep(3)
            print "Check your spelling and try again :( "
    
        # Random element in a string
    
    
        random_ness = random.choice("ABCDEFGHI*(#*#$()#*$)(E)(UWIJEDSH(*#U$()UDSLKH)UW*)$(*&#*(YE(*DY#*YUHSLDF:LKDDSDK")
        my_tuple = (calculate_input, random_ness, user_input, ask_name)
        new_tuple = my_tuple[1] 
        new_tuple1 = my_tuple[2]
        new_tuple2 = my_tuple[3]
        time.sleep(7)
        print str(ask_name) + str(password_output) + str(new_tuple) + str(new_tuple1) + str(new_tuple2) 
    
    def own_password():
        my_list = []
        ask_times = int(input("How many characters do you want ? (between 1 - 8) : "))
        time.sleep(10)
        if ask_times > 8:
            print "Invalid Request"
        elif ask_times < 1:
            print "Invalid Request"
        else:
            time.sleep(2)
            print "You CANNOT include symbols or numbers in this option !!! "
            for i in range(ask_times):
                user_ask = input("Enter the character: ")
                time.sleep(0.6)
                my_list.append(user_ask)
            own_password =  "".join(map(str,my_list))
            time.sleep(4)
            print "Your own password is : " + own_password
    
    
    
    
    strong_pass = input("Do you want a strong password or a weak one or make your own password !! ? : ")
    if strong_pass == "strong":
        strong_password()
    elif strong_pass == "weak":
        weak_password()
    elif strong_pass == "own":
        own_password()
    else :
        print "Invalid Request"
    
    time.sleep(3)
    print "Congrats, on creating your best password !!! I belived you used strong password generator because its the BEST !!"
    time.sleep(7)
    print "If not, no problem just restart the program and type strong when prompted !!! "
    time.sleep(6)
    print "Have a nice day !"
    

    This code is the answer for CodeHs Quiz too (if you had any ) !!!

    0 讨论(0)
  • 2020-12-22 17:31

    I know this question was posted back in 2011, but for those coming to it now in 2014 and beyond, I have one thing to say: RESIST THE URGE TO REINVENT THE WHEEL.

    In these situations your best bet is to search for open-source software, e.g., constrain your search to github results. By far the best thing I've found:

    https://github.com/redacted/XKCD-password-generator

    0 讨论(0)
提交回复
热议问题