Mercurial > hgrepos > Python > apps > py-cutils
comparison cutils/genpwd.py @ 235:11819361ea39
Implement option "-e" for genpwd to require a binary length instead of the output length.
This is effectively a minimum length.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Fri, 07 Feb 2025 19:32:45 +0100 |
| parents | c7dc57c44e8b |
| children | 939a8da6bc92 |
comparison
equal
deleted
inserted
replaced
| 234:c7dc57c44e8b | 235:11819361ea39 |
|---|---|
| 39 aparser = argparse.ArgumentParser( | 39 aparser = argparse.ArgumentParser( |
| 40 description="A simple password generator for password of a given" | 40 description="A simple password generator for password of a given" |
| 41 " length within a character repertoire", | 41 " length within a character repertoire", |
| 42 fromfile_prefix_chars='@') | 42 fromfile_prefix_chars='@') |
| 43 aparser.add_argument( | 43 aparser.add_argument( |
| 44 "--version", "-v", action="version", | |
| 45 version="%s (rv:%s)" % (__version__, __revision__)) | |
| 46 aparser.add_argument( | |
| 47 "-e", dest="use_bin_length", action="store_true", | |
| 48 help="For some repertoires make OUTPUT-LENGTH the number of bytes" | |
| 49 " that is to be read from random sources instead of output bytes") | |
| 50 aparser.add_argument( | |
| 44 "--repertoire", "--type", "-t", | 51 "--repertoire", "--type", "-t", |
| 45 choices=("web", "web-safe", "web-safe2", | 52 choices=("web", "web-safe", "web-safe2", |
| 46 "base64", "urlsafe-base64", "urlsafe", "base32", "ascii85", ), | 53 "base64", "urlsafe-base64", "urlsafe", "base32", "ascii85", ), |
| 47 default="web-safe2", | 54 default="web-safe2", |
| 48 help="Select the character repertoire. Default: web-safe2") | 55 help="Select the character repertoire. Default: web-safe2") |
| 49 aparser.add_argument( | |
| 50 "--version", "-v", action="version", | |
| 51 version="%s (rv:%s)" % (__version__, __revision__)) | |
| 52 aparser.add_argument( | 56 aparser.add_argument( |
| 53 "req_length", metavar="OUTPUT-LENGTH", type=int, | 57 "req_length", metavar="OUTPUT-LENGTH", type=int, |
| 54 help="The required length of the generated password") | 58 help="The required length of the generated password") |
| 55 | 59 |
| 56 opts = aparser.parse_args(args=argv) | 60 opts = aparser.parse_args(args=argv) |
| 61 pwd = gen_web(opts.req_length, WEB_SAFE_CHARS) | 65 pwd = gen_web(opts.req_length, WEB_SAFE_CHARS) |
| 62 elif opts.repertoire == "web-safe2": | 66 elif opts.repertoire == "web-safe2": |
| 63 pwd = gen_web(opts.req_length, WEB_SAFE2_CHARS) | 67 pwd = gen_web(opts.req_length, WEB_SAFE2_CHARS) |
| 64 elif opts.repertoire == "base64": | 68 elif opts.repertoire == "base64": |
| 65 encoder = base64.b64encode | 69 encoder = base64.b64encode |
| 66 pwd = gen_bin(opts.req_length, encoder) | 70 pwd = gen_bin(opts.req_length, opts.use_bin_length, encoder, |
| 71 rstrip_chars=b"=") | |
| 67 elif opts.repertoire in ("urlsafe-base64", "urlsafe"): | 72 elif opts.repertoire in ("urlsafe-base64", "urlsafe"): |
| 68 encoder = base64.urlsafe_b64encode | 73 encoder = base64.urlsafe_b64encode |
| 69 pwd = gen_bin(opts.req_length, encoder) | 74 pwd = gen_bin(opts.req_length, opts.use_bin_length, encoder, |
| 75 rstrip_chars=b"=") | |
| 70 elif opts.repertoire == "base32": | 76 elif opts.repertoire == "base32": |
| 71 encoder = base64.b32encode | 77 encoder = base64.b32encode |
| 72 pwd = gen_bin(opts.req_length, encoder) | 78 pwd = gen_bin(opts.req_length, opts.use_bin_length, encoder, |
| 79 rstrip_chars=b"=") | |
| 73 elif opts.repertoire == "ascii85": | 80 elif opts.repertoire == "ascii85": |
| 74 encoder = base64.a85encode | 81 encoder = base64.a85encode |
| 75 pwd = gen_bin(opts.req_length, encoder) | 82 pwd = gen_bin(opts.req_length, opts.use_bin_length, encoder) |
| 76 else: | 83 else: |
| 77 raise NotImplementedError("type not yet implemented: %s" | 84 raise NotImplementedError("type not yet implemented: %s" |
| 78 % opts.repertoire) | 85 % opts.repertoire) |
| 79 assert len(pwd) == opts.req_length | 86 if opts.use_bin_length: |
| 87 if len(pwd) < opts.req_length: | |
| 88 raise AssertionError("internal length mismatch") | |
| 89 else: | |
| 90 if len(pwd) != opts.req_length: | |
| 91 raise AssertionError("internal length mismatch") | |
| 80 if not PY2: | 92 if not PY2: |
| 81 pwd = pwd.decode("ascii") | 93 pwd = pwd.decode("ascii") |
| 82 print(pwd) | 94 print(pwd) |
| 83 | 95 |
| 84 | 96 |
| 100 else: | 112 else: |
| 101 pwd = bytes(pwd) | 113 pwd = bytes(pwd) |
| 102 return pwd | 114 return pwd |
| 103 | 115 |
| 104 | 116 |
| 105 def gen_bin(length, encoder): | 117 def gen_bin(length, use_bin_length, encoder, rstrip_chars=None): |
| 106 pwd = encoder(os.urandom(length)) | 118 pwd = encoder(os.urandom(length)) |
| 107 return pwd[:length] | 119 return pwd.rstrip(rstrip_chars) if use_bin_length else pwd[:length] |
| 108 | 120 |
| 109 | 121 |
| 110 if __name__ == "__main__": | 122 if __name__ == "__main__": |
| 111 main() | 123 main() |
