HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Gimme some random passwords

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
randomgimmepasswordssome

Problem

pwgen is a nice password generator utility.
When you run it, it fills the terminal with a bunch of random passwords,
giving you many options to choose from and pick something you like,
for example:

lvk3U7cKJYkl pLBJ007977Qx b9xhj8NWPfWQ
pMgUJBUuXwpG OAAqf6Y9TXqc fJOyxoGYCRSQ
bpbwp6f2MxEH fUYTJUqg0ZMB GjVVEQxuer0k
oqTEvV1LmdJu si47MkHNRpAw 3GKV8NdGMvwf


Although there are ports of pwgen in multiple systems,
it's not so easy to find in Windows.
So I put together a simple Python script that's more portable,
as it can run in any system with Python.

I added some extra features I often want:

  • Skip characters that may be ambiguous, such as l1ioO0Z2I



  • Avoid doubled characters (slow down typing)



Here it goes:

``
#!/usr/bin/env python

from __future__ import print_function

import random
import string
import re

from argparse import ArgumentParser

terminal_width = 80
terminal_height = 25

default_length = 12

alphabet_default = string.ascii_letters + string.digits
alphabet_complex = alphabet_default + '
~!@#$%^&*()_+-={}[];:<>?,./'
alphabet_easy = re.sub(r'[l1ioO0Z2I]', '', alphabet_default)

double_letter = re.compile(r'(.)\1')

def randomstring(alphabet, length=16):
return ''.join(random.choice(alphabet) for _ in range(length))

def has_double_letter(word):
return double_letter.search(word) is not None

def easy_to_type_randomstring(alphabet, length=16):
while True:
word = randomstring(alphabet, length)
if not has_double_letter(word):
return word

def pwgen(alphabet, easy, length=16):
for _ in range(terminal_height - 3):
for _ in range(terminal_width // (length + 1)):
if easy:
print(easy_to_type_randomstring(alphabet, length), end=' ')
else:
print(randomstring(alphabet, length), end=' ')
print()

def main():
parser = ArgumentParser(description='Generate random passwords')
parser.add_argument('-a', '--alphabet',

Solution

Looking at the following:

terminal_width = 80
terminal_height = 25

default_length = 12

alphabet_default = string.ascii_letters + string.digits
alphabet_complex = alphabet_default + '`~!@#$%^&*()_+-={}[];:<>?,./'
alphabet_easy = re.sub(r'[l1ioO0Z2I]', '', alphabet_default)

double_letter = re.compile(r'(.)\1')


you never change them, so they are constants. Constants are written ALL CAPS in Python as a convention.

elif len(alphabet) < length:
    length = len(alphabet)


Are you sure the user really wants what you are doing here? Maybe he wants a 20 character password using only the 10 digits, with this you are silently not doing what he expects.

Code Snippets

terminal_width = 80
terminal_height = 25

default_length = 12

alphabet_default = string.ascii_letters + string.digits
alphabet_complex = alphabet_default + '`~!@#$%^&*()_+-={}[];:<>?,./'
alphabet_easy = re.sub(r'[l1ioO0Z2I]', '', alphabet_default)

double_letter = re.compile(r'(.)\1')
elif len(alphabet) < length:
    length = len(alphabet)

Context

StackExchange Code Review Q#79276, answer score: 7

Revisions (0)

No revisions yet.