comparison cutils/genpwd.py @ 240:32616df2732e

Renamed algorithms/repertoire selection: use a "bin-" prefix when just the output of os.urandom() is encoded
author Franz Glasner <fzglas.hg@dom66.de>
date Sat, 08 Feb 2025 09:37:48 +0100
parents 1eae57292c7c
children d4501acb0a7c
comparison
equal deleted inserted replaced
239:1eae57292c7c 240:32616df2732e
48 help="For some repertoires make OUTPUT-LENGTH the number of bytes" 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") 49 " that is to be read from random sources instead of output bytes")
50 aparser.add_argument( 50 aparser.add_argument(
51 "--repertoire", "--type", "-t", 51 "--repertoire", "--type", "-t",
52 choices=("web", "web-safe", "web-safe2", 52 choices=("web", "web-safe", "web-safe2",
53 "base64", "urlsafe-base64", "urlsafe", "base32", "ascii85", ), 53 "bin-base64", "bin-urlsafe-base64", "bin-base32",
54 "bin-ascii85", ),
54 default="web-safe2", 55 default="web-safe2",
55 help="Select the character repertoire. Default: web-safe2") 56 help="Select the character repertoire. Default: web-safe2")
56 aparser.add_argument( 57 aparser.add_argument(
57 "req_length", metavar="OUTPUT-LENGTH", type=int, 58 "req_length", metavar="OUTPUT-LENGTH", type=int,
58 help="The required length of the generated output") 59 help="The required length of the generated output")
63 pwd = gen_from_repertoire(opts.req_length, WEB_CHARS) 64 pwd = gen_from_repertoire(opts.req_length, WEB_CHARS)
64 elif opts.repertoire == "web-safe": 65 elif opts.repertoire == "web-safe":
65 pwd = gen_from_repertoire(opts.req_length, WEB_SAFE_CHARS) 66 pwd = gen_from_repertoire(opts.req_length, WEB_SAFE_CHARS)
66 elif opts.repertoire == "web-safe2": 67 elif opts.repertoire == "web-safe2":
67 pwd = gen_from_repertoire(opts.req_length, WEB_SAFE2_CHARS) 68 pwd = gen_from_repertoire(opts.req_length, WEB_SAFE2_CHARS)
68 elif opts.repertoire == "base64": 69 elif opts.repertoire == "bin-base64":
69 encoder = base64.b64encode 70 encoder = base64.b64encode
70 pwd = gen_bin(opts.req_length, opts.use_bin_length, encoder, 71 pwd = gen_bin(opts.req_length, opts.use_bin_length, encoder,
71 rstrip_chars=b"=") 72 rstrip_chars=b"=")
72 elif opts.repertoire in ("urlsafe-base64", "urlsafe"): 73 elif opts.repertoire == "bin-urlsafe-base64":
73 encoder = base64.urlsafe_b64encode 74 encoder = base64.urlsafe_b64encode
74 pwd = gen_bin(opts.req_length, opts.use_bin_length, encoder, 75 pwd = gen_bin(opts.req_length, opts.use_bin_length, encoder,
75 rstrip_chars=b"=") 76 rstrip_chars=b"=")
76 elif opts.repertoire == "base32": 77 elif opts.repertoire == "bin-base32":
77 encoder = base64.b32encode 78 encoder = base64.b32encode
78 pwd = gen_bin(opts.req_length, opts.use_bin_length, encoder, 79 pwd = gen_bin(opts.req_length, opts.use_bin_length, encoder,
79 rstrip_chars=b"=") 80 rstrip_chars=b"=")
80 elif opts.repertoire == "ascii85": 81 elif opts.repertoire == "bin-ascii85":
81 encoder = base64.a85encode 82 encoder = base64.a85encode
82 pwd = gen_bin(opts.req_length, opts.use_bin_length, encoder) 83 pwd = gen_bin(opts.req_length, opts.use_bin_length, encoder)
83 else: 84 else:
84 raise NotImplementedError("type not yet implemented: %s" 85 raise NotImplementedError("type not yet implemented: %s"
85 % opts.repertoire) 86 % opts.repertoire)
93 pwd = pwd.decode("ascii") 94 pwd = pwd.decode("ascii")
94 print(pwd) 95 print(pwd)
95 96
96 97
97 def gen_from_repertoire(length, repertoire): 98 def gen_from_repertoire(length, repertoire):
99 """Select `length` characters randomly from given character repertoire
100 `repertoire`.
101
102 """
98 assert len(repertoire) <= 256 103 assert len(repertoire) <= 256
99 pwd = [] 104 pwd = []
100 while len(pwd) < length: 105 while len(pwd) < length:
101 rndbytes = os.urandom(16) 106 rndbytes = os.urandom(16)
102 for c in rndbytes: 107 for c in rndbytes:
112 pwd = bytes(pwd) 117 pwd = bytes(pwd)
113 return pwd 118 return pwd
114 119
115 120
116 def gen_bin(length, use_bin_length, encoder, rstrip_chars=None): 121 def gen_bin(length, use_bin_length, encoder, rstrip_chars=None):
122 """Generate from :func:`os.urandom` and just encode with given `encoder`.
123
124 """
117 pwd = encoder(os.urandom(length)) 125 pwd = encoder(os.urandom(length))
118 return pwd.rstrip(rstrip_chars) if use_bin_length else pwd[:length] 126 return pwd.rstrip(rstrip_chars) if use_bin_length else pwd[:length]
119 127
120 128
121 if __name__ == "__main__": 129 if __name__ == "__main__":