2

i want generate password including lower case and upper case and numbers using python but it should guarantee that all these 3 kinds has been used. so far i wrote this but it does not guarantee that all 3 kinds of characters are being used. i want divide the 8 character to 2 part. first 3 and last 5. then make sure in the firs part all 3 kinds of character are being used then shuffle them with the next part but i dont know how to code that.

import random
a = 0
password = ''
while a < 8:
    if random.randint(0, 61) < 10:
        password += chr(random.randint(48, 57))
    elif 10<random.randint(0, 61)<36:
        password += chr(random.randint(65, 90))
    else:
        password += chr(random.randint(97, 122))
    a += 1
print(password)
Jaxian
  • 1,088
  • 7
  • 14

3 Answers3

3

As you said: First three positions are randomly chosen from upper- and lowercase characters and digits, respectively, and the rest are randomly chosen from all characters, then shuffle.

from random import choice, shuffle
from string import ascii_uppercase, ascii_lowercase, digits
pwd = [choice(ascii_lowercase), choice(ascii_uppercase), choice(digits)] \
      + [choice(ascii_lowercase + ascii_uppercase + digits) for _ in range(5)]
shuffle(pwd)
pwd = ''.join(pwd)

Note that this way digits might be a bit 'underrepresented', as they are chosen randomly from the bulk of all the available characters, so there is a chance of 10/62 that any character after the first three will be a digit. If you want 1/3 of characters to be digits (which might not be a good idea -- see below), you could first randomly chose one character group, each with 1/3 chance, and then a character form that group:

pwd = [choice(ascii_lowercase), choice(ascii_uppercase), choice(digits)] \
      + [choice(choice([ascii_lowercase, ascii_uppercase, digits])) for _ in range(5)]

But note that this will decrease the randomness, and thus the security of the password -- but so does the requirement of having at least one of each of the three groups.

tobias_k
  • 74,298
  • 11
  • 102
  • 155
  • I think it was better before the edit... pretty sure changing the relative probabilities of the characters is bad from a security perspective. – glibdud Jul 06 '16 at 12:47
  • @glibdud Agreed. Added a notice. – tobias_k Jul 06 '16 at 12:50
  • Better. I still don't see the value of that section, though... the first half completely addresses the question. (+1 either way, though) – glibdud Jul 06 '16 at 12:53
0

Your question consists of 3 parts:

  1. divide the 8 character to 2 part - first 3 and last 5 - (string slicing)
  2. make sure in the first part all 3 kinds of character are being used (validating passwords)
  3. shuffle the characters (shuffling strings)

Part1: slicing strings

Here's a good tutorial teaching how to slice strings using python..

In your case, if you insert this at the end of your code...

print(password[:3])
print(password[3:])

... you'll see the first 3 chars and the last 5.


Part2: validating passwords

A good answer can be found here.

def password_check(password):
    # calculating the length
    length_error = len(password) < 8

    # searching for digits
    digit_error = re.search(r"\d", password) is None

    # searching for uppercase
    uppercase_error = re.search(r"[A-Z]", password) is None

    # searching for lowercase
    lowercase_error = re.search(r"[a-z]", password) is None

     # overall result
    password_ok = not ( length_error or digit_error or uppercase_error or lowercase_error)

    return password_ok

password_check(password) 

This function will return True if satisfies all conditions, and False if not.


Part3: shuffling strings

if password_check(password) == True:
    new_pwd = ''.join(random.sample(password,len(password)))
    print new_pwd

This code will shuffle the whole password and assign it to a new variable called new_pwd


ps. The whole code can be found here!

Community
  • 1
  • 1
dot.Py
  • 4,535
  • 3
  • 24
  • 47
0

You could use regular expressions and check if any char matches the regular expression.

import re
string = "AaBbCc12"

if re.search('[a-z]',string)\
and re.search('[0-9]',string)\ 
and re.search('[A-Z]',string):
    print("This is a string you are looking for")
else:
    print("Nope")

This is a rather inelegant solution but is the fastest in terms of understanding and adaptability.

madonius
  • 306
  • 2
  • 6