[issue33360] ALternative recipe for password using secrets

2018-04-26 Thread Juan Postlbauer

Juan Postlbauer  added the comment:

Just a clarification: by "infinite potential loop" I meant a loop that 
*theoretically* could last forever. Of course in practice it won't, but my 
experiments show that for the conditions in the example in average the current 
recipe generates 5 tentative passwords before finding one that fulfills all 
conditions.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue33360] ALternative recipe for password using secrets

2018-04-25 Thread Juan Postlbauer

New submission from Juan Postlbauer :

Chapter 15.3.4 shows a recipe with an infinite potential loop.
An alternative would be:

''.join(sorted([choice(string.ascii_lowercase) for i in 
range(1)]+[choice(string.ascii_uppercase) for i in 
range(1)]+[choice(string.digits) for i in 
range(3)]+[choice(string.ascii_letters+string.digits) for i in 
range(10-(1+1+3))],key=lambda x:randbelow(4096)))

Can we assume secrets.SystemRandom is cryptographically strong but has all the 
methods of random??
If so it can be done in a more understandable way by using choices and shuffle. 
(see 2 examples below)

def generate_password_random(totalchars=10,minlower=1,minupper=1,mindigits=3):
restcount= totalchars-(minlower+minupper+mindigits)
if restcount<0:
raise ValueError("Impossible conditions")
lowerchars=random.choices(string.ascii_lowercase,k=minlower)
upperchars=random.choices(string.ascii_uppercase,k=minupper)
digitchars=random.choices(string.digits,k=mindigits)
restchars=random.choices(string.ascii_letters+string.digits,k=restcount)
allchars=lowerchars+upperchars+digitchars+restchars
random.shuffle(allchars)
password=''.join(allchars)
return password

def generate_password_secrets(totalchars=10,minlower=1,minupper=1,mindigits=3):
restcount= totalchars- (minlower+minupper+mindigits)
if restcount<0:
raise ValueError("Impossible conditions")
lowerchars=[secrets.choice(string.ascii_lowercase) for _ in range(minlower)]
upperchars=[secrets.choice(string.ascii_uppercase) for _ in range(minupper)]
digitchars=[secrets.choice(string.digits) for _ in range (mindigits)]
restchars=[secrets.choice(string.ascii_letters+string.digits) for _ in 
range (restcount)]
allchars=lowerchars+upperchars+digitchars+restchars
allchars.sort(key=lambda x:secrets.randbelow(4096))
password=''.join(allchars)
return password

--
assignee: docs@python
components: Documentation
messages: 315763
nosy: docs@python, jpc4242
priority: normal
severity: normal
status: open
title: ALternative recipe for password using secrets
type: enhancement
versions: Python 3.6

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com