Skip to content

Instantly share code, notes, and snippets.

@textbook
Created April 29, 2020 17:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save textbook/3225727cc151f316c664cd78299c1634 to your computer and use it in GitHub Desktop.
Save textbook/3225727cc151f316c664cd78299c1634 to your computer and use it in GitHub Desktop.
Simple Python password creator
from itertools import cycle
from random import choice, shuffle
from string import ascii_lowercase, ascii_uppercase, digits, punctuation
def generate_password(length: int = 20, *, use_symbols: bool = True) -> str:
"""Generate random passwords, with or without symbols.
Implementation ensures a fairly even balance of each character
class, at the cost of entropy (e.g. for a four-character password
with symbols there are only 5,191,680 possible combinations, rather
than 78,074,896).
>>> from random import seed
>>> seed(0)
>>> generate_password()
'm7s;1)j[Yz^Q7G86#JiE'
>>> generate_password(use_symbols=True)
'o$3k0%M~0H:Q&xRg45Sz'
>>> generate_password(use_symbols=False)
'o15HGC4sfzpv42Tb9CYM'
>>> generate_password(10)
'SAc-5h9(Kp'
>>> generate_password(10, use_symbols=True)
'aDUs%3z8E#'
>>> generate_password(10, use_symbols=False)
'Ap01v8gGFn'
>>> generate_password(0)
''
>>> generate_password(-1)
''
>>> generate_password("foo")
Traceback (most recent call last):
...
TypeError: 'str' object cannot be interpreted as an integer
"""
cases = [ascii_lowercase, ascii_uppercase, digits]
if use_symbols:
cases.append(punctuation)
characters = [
choice(case)
for _, case
in zip(range(length), cycle(cases))
]
shuffle(characters)
return "".join(characters)
if __name__ == "__main__":
import doctest
doctest.testmod()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment