-
Notifications
You must be signed in to change notification settings - Fork 0
/
genKey.py
executable file
·163 lines (132 loc) · 5.08 KB
/
genKey.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#!/usr/bin/env python3
#
# genKey.py: Generate a random key from given symbols and length.
# 2016-01-04: Written by Steven J. DeRose.
#
import sys
import argparse
import string
import random
import codecs
__metadata__ = {
"title" : "genKey",
"description" : "Generate a random key from given symbols and length.",
"rightsHolder" : "Steven J. DeRose",
"creator" : "http://viaf.org/viaf/50334488",
"type" : "http://purl.org/dc/dcmitype/Software",
"language" : "Python 3.7",
"created" : "2016-01-04",
"modified" : "2020-03-01",
"publisher" : "http://github.com/sderose",
"license" : "https://creativecommons.org/licenses/by-sa/3.0/"
}
__version__ = __metadata__['modified']
descr = """
=Description=
Generate a random key, from a given set of symbols and of a given length.
==Notes==
Use '--symbols S' to choose what symbols to draw from:
* 'ascii' only includes printable characters.
* 'alpha', 'upper', 'lower', 'alphanum', and 'digits' only draw from ASCII.
* 'latin1' uses 'ascii' plus 'letters' from the upper half.
* 'utf8' uses string.printable, and so may depend on locale.
* 'hex' only includes uppercase versions of A-F.
* Characters are drawn with uniform probability (thus, letters are no more
likely than digits or punctuation with 'alphanum', etc.).
* Words are drawn from a file that should contain one word per line.
The default file is F</usr/share/dict/words> (but see '--dict').
=Related Commands=
`randomRecords`, `gendsa`, `genpkey`, `genrsa`, `openssl rand`.
=Known bugs and Limitations=
Randomness of the key is whatever Python supplies. This may or may not
be good enough for your needs.
=Rights=
Copyright 2016-01-04 by Steven J. DeRose.
This work is licensed under a Creative Commons
Attribution-Share Alike 3.0 Unported License. For further information on
this license, see http://creativecommons.org/licenses/by-sa/3.0/.
For the most recent version, see [http://www.derose.net/steve/utilities] or
[http://github.com/sderose].
=Options=
"""
###############################################################################
#
def processOptions():
try:
from BlockFormatter import BlockFormatter
parser = argparse.ArgumentParser(
description=descr, formatter_class=BlockFormatter)
except ImportError:
parser = argparse.ArgumentParser(description=descr)
parser.add_argument(
"--dencoding", type=str, metavar='E', default="utf-8",
help='Assume this character set for dictionary files. Default: utf-8.')
parser.add_argument(
"--dict", type=str, default='/usr/share/dict/words',
help='A dictionary file to use with --symbols words.')
parser.add_argument(
"--length", "-n", type=int, default=12, metavar='N',
help='length of key.')
parser.add_argument(
"--punc", type=str, default='._!@*~?',
help='Which punctuation to allow.')
parser.add_argument(
"--quiet", "-q", action='store_true',
help='Suppress most messages.')
parser.add_argument(
"--seed", type=int,
help='Seed for random-number generator.')
parser.add_argument(
"--symbols", type=str, default="alphanum",
choices=[ 'ascii', 'latin1', 'alpha', 'upper', 'lower',
'alphanum', 'digits', 'hex', 'utf8', 'words' ],
help='Which possible set of symbols to draw from.')
parser.add_argument(
"--verbose", "-v", action='count', default=0,
help='Add more messages (repeatable).')
parser.add_argument(
"--version", action='version', version=__version__,
help='Display version information, then exit.')
args0 = parser.parse_args()
return(args0)
###############################################################################
# Main
#
args = processOptions()
if (args.seed): random.seed(args.seed)
symbolSet = None
if (args.symbols == 'alpha'):
symbolSet = string.ascii_letters
elif (args.symbols == 'upper'):
symbolSet = string.ascii_uppercase
elif (args.symbols == 'lower'):
symbolSet = string.ascii_lowercase
elif (args.symbols == 'alphanum'):
symbolSet = string.ascii_letters + string.digits
elif (args.symbols == 'digits'):
symbolSet = string.digits
elif (args.symbols == 'hex'):
symbolSet = string.digits + 'ABCDEF' # Only one case!
elif (args.symbols == 'ascii'):
symbolSet = string.ascii_letters + string.digits + string.punctuation
elif (args.symbols == 'latin1'):
symbolSet = string.ascii_letters + string.digits + string.punctuation
for i in range(161, 255): # No Yen / DEL, please.
c = chr(i)
if (c.isalpha()): symbolSet += c
elif (args.symbols == 'utf8'):
symbolSet = string.printable
elif (args.symbols == 'words'):
dfh = codecs.open(args.dict, 'rw', encoding=args.dencoding)
symbolSet = dfh.read().split()
dfh.close()
else:
print("Unknown symbol set '%s'." % (args.symbols))
sys.exit()
symbolSetLength = len(symbolSet)
key = ""
for f in (range(args.length)):
key += symbolSet[random.randint(0, symbolSetLength)]
if (args.symbols == 'words'):
key += ' '
print(key)