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