Created
July 12, 2019 01:21
-
-
Save serverwentdown/ff721725a2db724132dd631bdb5a8994 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import random | |
import math | |
import string | |
import sys | |
import click | |
# correct horse battery staple | |
def load_dictionary(d="/usr/share/dict/words"): | |
f = open(d, "r") | |
words = f.readlines() | |
return list( | |
filter( | |
lambda w: w.isalpha(), | |
map(lambda w: w.strip().lower(), words) | |
) | |
) | |
def pick_words(words, n): | |
return random.choices(words, k=n) | |
def generate_password(words, sep="-", n=6, num=False): | |
words = pick_words(words, n) | |
if num: | |
for i in range(n): | |
digit = random.choice(string.digits) | |
words.insert(n-i-1, digit) | |
return sep.join(words) | |
@click.command() | |
@click.option("-c", "--count", default=4, help="Number of passwords to generate") | |
@click.option("-w", "--words", default=4, help="Number of words in a password") | |
@click.option("-s", "--sep", default="-", help="Seperator between words") | |
@click.option("--num/--no-num", default=False, help="Enable/disable adding numbers between words") | |
@click.option("--info/--no-info", default=True, help="Show/hide strength information") | |
@click.option("-d", "--dictionary", default="/usr/share/dict/words", help="Use a custom dictionary") | |
def program(count, words, sep, num, info, dictionary): | |
"""Generate a password from the system dictionary. xkcd.com/936""" | |
d = load_dictionary(dictionary) | |
if info: | |
combinations = len(d) ** words | |
if num: | |
combinations *= len(string.digits) ** words | |
print("With these options, there are {} possible passwords".format(combinations), file=sys.stderr) | |
conventional_set = len(string.ascii_letters) + len(string.digits) + len(string.punctuation) | |
conventional = math.ceil(math.log(combinations, conventional_set)) | |
print("The strength is equivalent to a {} character \"strong\" password".format(conventional), file=sys.stderr) | |
print(file=sys.stderr) | |
for i in range(count): | |
p = generate_password(d, sep=sep, n=words, num=num) | |
print(p) | |
if __name__ == "__main__": | |
program() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment