It looks likes what I intended to report as a wish for a --slow option got some attention recently. See bug #726578.
I'm attaching the little script I wrote in order to understand how slow a switch to /dev/random would make pwgen. It has a trigger displaying available entropy when things are too long. It might help other. Try "pwgen2 16 16" a few times in a row.
#!/usr/bin/python3
#
# Password generator from /dev/random
# (C) 2012 Nirgal Vourgère - GPL3+ license
import sys
import struct
import signal
def entropy_avail():
"""
Returns how many entropy bits the kernel has gathered.
This requieres a linux kernel >= 2.3.16.
Raises FileNotFoundError if not found
"""
fd = open('/proc/sys/kernel/random/entropy_avail')
bits = fd.read()
fd.close()
bits = int(bits)
return bits
def dummy_sighandler(signum, frame):
"""
Dummy signal handler that does nothing.
But InterruptedError is still raised.
"""
pass
def get_password(pw_length,
alphabet='ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789'):
assert len(alphabet) <= 256, "Alphabet can't have more than 256
choices. Sorry." # We can't go further reading 1 byte
random_dev = open('/dev/random', mode='rb', buffering=0)
result = ''
verbose_length = 0
# We want to be notified in 3 seconds if we are not done
signal.signal(signal.SIGALRM, dummy_sighandler)
signal.alarm(3)
while len(result) < pw_length:
try:
rnd = struct.unpack('B', random_dev.read(1))[0]
except InterruptedError:
msg = 'Generating passwords. Please wait. Password
length: %d bytes, available entropy: %d bits...' % (len(result),
entropy_avail())
verbose_length = len(msg)
print('\r' + msg, end='', file=sys.stderr)
signal.alarm(3)
continue
result += alphabet[rnd % len(alphabet)]
signal.signal(signal.SIGALRM, signal.SIG_IGN)
random_dev.close()
if verbose_length:
print(file=sys.stderr)
return result
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description='Generate random
passwords.')
parser.add_argument('pw_length', metavar='pw_length', type=int,
nargs='?',
default=16, help='password length')
parser.add_argument('num_pw', metavar='num_pw', type=int, nargs='?',
default=1, help='how many passwords to show')
parser.add_argument('--show-entropy', action='store_true',
default=False,
help='Show entropy count')
args = parser.parse_args()
if (args.show_entropy):
try:
print('Available entropy: %d bytes' %
(entropy_avail()//8), file=sys.stderr)
except FileNotFoundError:
print('Your system does not support entropy status
repporting.', file=sys.stderr)
for i in range(args.num_pw):
print(get_password(args.pw_length))
signature.asc
Description: OpenPGP digital signature

