zora-cli 0.1.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- zora/__init__.py +1 -0
- zora/cli.py +226 -0
- zora_cli-0.1.2.dist-info/METADATA +1021 -0
- zora_cli-0.1.2.dist-info/RECORD +8 -0
- zora_cli-0.1.2.dist-info/WHEEL +5 -0
- zora_cli-0.1.2.dist-info/entry_points.txt +2 -0
- zora_cli-0.1.2.dist-info/licenses/LICENSE +216 -0
- zora_cli-0.1.2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,1021 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: zora-cli
|
|
3
|
+
Version: 0.1.2
|
|
4
|
+
Summary: Cryptographically secure generator of random keys with tons of options and customizations.
|
|
5
|
+
Author: zscopuv
|
|
6
|
+
License: ZORA SOURCE-AVAILABLE LICENSE
|
|
7
|
+
Version 1.0
|
|
8
|
+
|
|
9
|
+
Copyright © 2026 radecekq
|
|
10
|
+
All rights reserved.
|
|
11
|
+
|
|
12
|
+
1. DEFINITIONS
|
|
13
|
+
|
|
14
|
+
For the purposes of this License:
|
|
15
|
+
|
|
16
|
+
"Software" means the Zora software, including its source code, documentation,
|
|
17
|
+
configuration files, assets, and any other materials distributed with the
|
|
18
|
+
Software.
|
|
19
|
+
|
|
20
|
+
"Original Software" means the Software as distributed by the Copyright Holder.
|
|
21
|
+
|
|
22
|
+
"Modified Version" means any version of the Software that has been altered,
|
|
23
|
+
adapted, translated, extended, refactored, or otherwise changed from the
|
|
24
|
+
Original Software.
|
|
25
|
+
|
|
26
|
+
"Copyright Holder" means the individual or entity that owns the copyright in
|
|
27
|
+
the Software.
|
|
28
|
+
|
|
29
|
+
"User" means any individual or organization obtaining access to the Software.
|
|
30
|
+
|
|
31
|
+
"Redistribution" means providing, publishing, transmitting, selling,
|
|
32
|
+
licensing, sublicensing, uploading, mirroring, or otherwise making the
|
|
33
|
+
Software or a Modified Version available to any third party.
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
2. GRANT OF RIGHTS
|
|
37
|
+
|
|
38
|
+
Subject to the terms and conditions of this License, the Copyright Holder
|
|
39
|
+
grants the User a limited, non-exclusive, non-transferable, revocable license
|
|
40
|
+
to:
|
|
41
|
+
|
|
42
|
+
a. access and inspect the source code of the Software;
|
|
43
|
+
|
|
44
|
+
b. copy the Software for personal use and development;
|
|
45
|
+
|
|
46
|
+
c. create private forks of the Software;
|
|
47
|
+
|
|
48
|
+
d. modify, adapt, extend, or otherwise alter the Software;
|
|
49
|
+
|
|
50
|
+
e. compile and execute the Software and Modified Versions for personal
|
|
51
|
+
use; and
|
|
52
|
+
|
|
53
|
+
f. use the Software and Modified Versions for non-commercial purposes.
|
|
54
|
+
|
|
55
|
+
These permissions do not constitute a transfer of ownership or copyright.
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
3. REDISTRIBUTION PROHIBITED
|
|
59
|
+
|
|
60
|
+
The User may not, without prior written permission from the Copyright Holder:
|
|
61
|
+
|
|
62
|
+
a. redistribute the Original Software;
|
|
63
|
+
|
|
64
|
+
b. redistribute any Modified Version;
|
|
65
|
+
|
|
66
|
+
c. publish a fork of the Software;
|
|
67
|
+
|
|
68
|
+
d. publish source code derived from the Software;
|
|
69
|
+
|
|
70
|
+
e. distribute compiled binaries or executable versions of the Software
|
|
71
|
+
or a Modified Version;
|
|
72
|
+
|
|
73
|
+
f. upload the Software or a Modified Version to another repository,
|
|
74
|
+
package registry, download service, file-sharing service, or similar
|
|
75
|
+
distribution platform;
|
|
76
|
+
|
|
77
|
+
g. sell, sublicense, rent, lease, or otherwise transfer the Software or
|
|
78
|
+
a Modified Version to another person or organization; or
|
|
79
|
+
|
|
80
|
+
h. make the Software or a Modified Version publicly available through
|
|
81
|
+
any medium.
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
4. PRIVATE FORKS
|
|
85
|
+
|
|
86
|
+
The User may create and maintain private forks of the Software for personal
|
|
87
|
+
development, experimentation, testing, education, or other lawful purposes.
|
|
88
|
+
|
|
89
|
+
A private fork must not be made available to third parties without the
|
|
90
|
+
express written permission of the Copyright Holder.
|
|
91
|
+
|
|
92
|
+
Nothing in this section grants permission to publish or redistribute a fork.
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
5. MODIFICATIONS
|
|
96
|
+
|
|
97
|
+
The User is expressly permitted to modify the Software for private use.
|
|
98
|
+
|
|
99
|
+
Modifications may include, but are not limited to:
|
|
100
|
+
|
|
101
|
+
- adding or removing functionality;
|
|
102
|
+
- changing the user interface;
|
|
103
|
+
- changing configuration;
|
|
104
|
+
- fixing bugs;
|
|
105
|
+
- refactoring code;
|
|
106
|
+
- creating experimental features; and
|
|
107
|
+
- adapting the Software for personal environments.
|
|
108
|
+
|
|
109
|
+
However, the creation of a Modified Version does not grant the User any
|
|
110
|
+
additional right to redistribute that Modified Version.
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
6. COPYRIGHT AND OWNERSHIP
|
|
114
|
+
|
|
115
|
+
The Software remains the property of the Copyright Holder.
|
|
116
|
+
|
|
117
|
+
This License does not transfer ownership of the Software, its source code,
|
|
118
|
+
copyright, trademarks, trade names, or other intellectual property rights.
|
|
119
|
+
|
|
120
|
+
All rights not expressly granted by this License are reserved by the
|
|
121
|
+
Copyright Holder.
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
7. ATTRIBUTION
|
|
125
|
+
|
|
126
|
+
If the Software or a Modified Version is used privately, the User is
|
|
127
|
+
encouraged to preserve all existing copyright notices, license notices,
|
|
128
|
+
author information, and attribution contained within the Software.
|
|
129
|
+
|
|
130
|
+
Nothing in this License permits the removal of copyright notices for the
|
|
131
|
+
purpose of claiming ownership of the Original Software.
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
8. COMMERCIAL USE
|
|
135
|
+
|
|
136
|
+
Commercial use, including incorporation of the Software into a commercial
|
|
137
|
+
product or service, is not permitted unless expressly authorized in writing
|
|
138
|
+
by the Copyright Holder.
|
|
139
|
+
|
|
140
|
+
The Copyright Holder may grant separate commercial licenses at their
|
|
141
|
+
discretion.
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
9. REQUESTS FOR REDISTRIBUTION
|
|
145
|
+
|
|
146
|
+
A User wishing to redistribute the Software or a Modified Version may
|
|
147
|
+
contact the Copyright Holder and request explicit permission.
|
|
148
|
+
|
|
149
|
+
Permission may be granted or denied at the sole discretion of the Copyright
|
|
150
|
+
Holder.
|
|
151
|
+
|
|
152
|
+
Any permission to redistribute may be subject to additional terms and
|
|
153
|
+
conditions established by the Copyright Holder.
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
10. NO WARRANTY
|
|
157
|
+
|
|
158
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
159
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
160
|
+
FOR A PARTICULAR PURPOSE, TITLE, OR NON-INFRINGEMENT.
|
|
161
|
+
|
|
162
|
+
THE COPYRIGHT HOLDER SHALL NOT BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER
|
|
163
|
+
LIABILITY ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
|
164
|
+
OR OTHER DEALINGS IN THE SOFTWARE.
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
11. LIMITATION OF LIABILITY
|
|
168
|
+
|
|
169
|
+
TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THE COPYRIGHT HOLDER
|
|
170
|
+
SHALL NOT BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL,
|
|
171
|
+
OR EXEMPLARY DAMAGES ARISING FROM THE USE OR INABILITY TO USE THE SOFTWARE.
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
12. TERMINATION
|
|
175
|
+
|
|
176
|
+
This License automatically terminates if the User violates any of its terms.
|
|
177
|
+
|
|
178
|
+
Upon termination, the User must cease all use of the Software and destroy
|
|
179
|
+
copies of the Software and Modified Versions in their possession or control,
|
|
180
|
+
except where retention is required by applicable law.
|
|
181
|
+
|
|
182
|
+
Permissions may be reinstated only through explicit written authorization
|
|
183
|
+
from the Copyright Holder.
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
13. SEVERABILITY
|
|
187
|
+
|
|
188
|
+
If any provision of this License is determined to be invalid or
|
|
189
|
+
unenforceable, the remaining provisions shall remain in full force and
|
|
190
|
+
effect.
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
14. ENTIRE AGREEMENT
|
|
194
|
+
|
|
195
|
+
This License constitutes the entire agreement concerning the Software and
|
|
196
|
+
supersedes any prior or contemporaneous understanding concerning the rights
|
|
197
|
+
granted under this License.
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
15. RESERVATION OF RIGHTS
|
|
201
|
+
|
|
202
|
+
The Copyright Holder reserves all rights not expressly granted by this
|
|
203
|
+
License.
|
|
204
|
+
|
|
205
|
+
No permission should be inferred merely because a particular restriction is
|
|
206
|
+
not explicitly stated.
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
16. LICENSE VERSION
|
|
210
|
+
|
|
211
|
+
This license is designated:
|
|
212
|
+
|
|
213
|
+
Zora Source-Available License v1.0
|
|
214
|
+
|
|
215
|
+
Future versions of this License may be published by the Copyright Holder.
|
|
216
|
+
Unless explicitly stated otherwise, a particular version of the Software
|
|
217
|
+
remains governed by the license version distributed with that version.
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
Copyright © 2026 radecekq
|
|
221
|
+
All rights reserved.
|
|
222
|
+
|
|
223
|
+
Requires-Python: >=3.9
|
|
224
|
+
Description-Content-Type: text/markdown
|
|
225
|
+
License-File: LICENSE
|
|
226
|
+
Requires-Dist: colorama==0.4.6
|
|
227
|
+
Dynamic: license-file
|
|
228
|
+
|
|
229
|
+
# 
|
|
230
|
+
> **Early release (`v0.1.2`)**
|
|
231
|
+
|
|
232
|
+
Zora generates random keys using Python's cryptographically secure
|
|
233
|
+
`secrets` module by default. It supports customizable character sets,
|
|
234
|
+
charset presets, prefixes, suffixes, grouping, multiple outputs, file
|
|
235
|
+
output, entropy estimation, and an optional deterministic PRNG mode.
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## Features
|
|
241
|
+
|
|
242
|
+
- 🔐 **Cryptographically secure** generation by default
|
|
243
|
+
- ⚠️ Optional insecure **PRNG mode** with `--unsafe`
|
|
244
|
+
- 🎲 **Deterministic generation** with `--seed` in unsafe mode
|
|
245
|
+
- 🔤 **Custom character sets**
|
|
246
|
+
- 🧩 **Composable charset presets** such as `@letters@digits`
|
|
247
|
+
- 🔢 **Built-in hexadecimal, octal, binary, digit, and symbol presets**
|
|
248
|
+
- ➕ Add **custom characters** to presets
|
|
249
|
+
- 📏 Configurable **key length**
|
|
250
|
+
- 📦 Generate **multiple keys** at once
|
|
251
|
+
- 🔗 Add **prefixes and suffixes**
|
|
252
|
+
- 📐 **Group keys with custom separators**
|
|
253
|
+
- 💾 Write generated **keys to a file**
|
|
254
|
+
- 📊 Calculate **theoretical entropy**
|
|
255
|
+
- 💪 **Estimate key strength** from entropy
|
|
256
|
+
- ⏱️ Display **generation time**
|
|
257
|
+
- 🤫 **Quiet mode** for scripting
|
|
258
|
+
- 📋 **Charset preset listing**
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
# Usage
|
|
262
|
+
|
|
263
|
+
Basic usage:
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
python zora.py LENGTH [OPTIONS]
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
For example:
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
python zora.py 32
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
Example output:
|
|
276
|
+
|
|
277
|
+
```text
|
|
278
|
+
GxKqTnJpYwRzLhBcVfQmNsXeUaPkTdWr
|
|
279
|
+
|
|
280
|
+
Timer: 13ms elapsed
|
|
281
|
+
Charset: 52
|
|
282
|
+
Entropy: 182.41 bits
|
|
283
|
+
Strength: Very strong
|
|
284
|
+
Generator: CSPRNG
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
# Arguments
|
|
290
|
+
|
|
291
|
+
## `length`
|
|
292
|
+
|
|
293
|
+
The length of the random portion of the generated key.
|
|
294
|
+
|
|
295
|
+
```bash
|
|
296
|
+
python zora.py 32
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
The value must be greater than `0`.
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## `--charset`
|
|
304
|
+
|
|
305
|
+
Select the character set used to generate keys.
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
python zora.py 32 --charset @digits
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
By default:
|
|
312
|
+
|
|
313
|
+
```text
|
|
314
|
+
@letters
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
is used.
|
|
318
|
+
|
|
319
|
+
Zora supports both predefined charset presets and literal characters.
|
|
320
|
+
|
|
321
|
+
### Presets
|
|
322
|
+
|
|
323
|
+
Use `--charset-list` to display all available presets:
|
|
324
|
+
|
|
325
|
+
```bash
|
|
326
|
+
python zora.py --charset-list
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
Currently available presets:
|
|
330
|
+
|
|
331
|
+
| Preset | Characters |
|
|
332
|
+
| ---------- | ----------------------------- |
|
|
333
|
+
| `@digits` | `0-9` |
|
|
334
|
+
| `@letters` | `a-zA-Z` |
|
|
335
|
+
| `@lower` | `a-z` |
|
|
336
|
+
| `@upper` | `A-Z` |
|
|
337
|
+
| `@hex` | `0-9ABCDEFabcdef` |
|
|
338
|
+
| `@oct` | `01234567` |
|
|
339
|
+
| `@bin` | `01` |
|
|
340
|
+
| `@special` | all punctuation/symbol characters |
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
|
|
344
|
+
## Combining presets
|
|
345
|
+
|
|
346
|
+
Presets can be combined:
|
|
347
|
+
|
|
348
|
+
```bash
|
|
349
|
+
python zora.py 32 --charset @letters@digits
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
This creates an alphanumeric character set.
|
|
353
|
+
|
|
354
|
+
Multiple presets can be combined:
|
|
355
|
+
|
|
356
|
+
```bash
|
|
357
|
+
python zora.py 32 --charset @upper@lower@digits
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
Duplicate characters are automatically removed.
|
|
361
|
+
|
|
362
|
+
For example:
|
|
363
|
+
|
|
364
|
+
```text
|
|
365
|
+
@letters@upper
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
does not contain uppercase characters twice.
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
372
|
+
## Custom characters
|
|
373
|
+
|
|
374
|
+
Literal characters can be included alongside presets.
|
|
375
|
+
|
|
376
|
+
For example:
|
|
377
|
+
|
|
378
|
+
```bash
|
|
379
|
+
python zora.py 32 --charset @hexXYZ
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
This means:
|
|
383
|
+
|
|
384
|
+
```text
|
|
385
|
+
@hex + X + Y + Z
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
Another example:
|
|
389
|
+
|
|
390
|
+
```bash
|
|
391
|
+
python zora.py 32 --charset XYZ@hex
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
means:
|
|
395
|
+
|
|
396
|
+
```text
|
|
397
|
+
X + Y + Z + @hex
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
This allows arbitrary character sets without needing to add a new preset.
|
|
401
|
+
|
|
402
|
+
---
|
|
403
|
+
|
|
404
|
+
# `--charset-list`
|
|
405
|
+
|
|
406
|
+
Display the available charset presets:
|
|
407
|
+
|
|
408
|
+
```bash
|
|
409
|
+
python zora.py --charset-list
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
Example:
|
|
413
|
+
|
|
414
|
+
```text
|
|
415
|
+
Available charsets:
|
|
416
|
+
|
|
417
|
+
@digits
|
|
418
|
+
@letters
|
|
419
|
+
@lower
|
|
420
|
+
@upper
|
|
421
|
+
@hex
|
|
422
|
+
@oct
|
|
423
|
+
@bin
|
|
424
|
+
@special
|
|
425
|
+
|
|
426
|
+
Use as:
|
|
427
|
+
|
|
428
|
+
zora --charset @digits
|
|
429
|
+
zora --charset @letters@digits
|
|
430
|
+
zora --charset @hexXYZ
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
---
|
|
434
|
+
|
|
435
|
+
# Multiple keys
|
|
436
|
+
|
|
437
|
+
Use `-n` or `--count`:
|
|
438
|
+
|
|
439
|
+
```bash
|
|
440
|
+
python zora.py 32 --count 10
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
or:
|
|
444
|
+
|
|
445
|
+
```bash
|
|
446
|
+
python zora.py 32 -n 10
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
Zora generates each key independently.
|
|
450
|
+
|
|
451
|
+
When using the secure default generator, each key is generated using the
|
|
452
|
+
cryptographically secure random generator.
|
|
453
|
+
|
|
454
|
+
---
|
|
455
|
+
|
|
456
|
+
# Prefixes and suffixes
|
|
457
|
+
|
|
458
|
+
Add a prefix:
|
|
459
|
+
|
|
460
|
+
```bash
|
|
461
|
+
python zora.py 32 --prefix "AUTH_"
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
Example:
|
|
465
|
+
|
|
466
|
+
```text
|
|
467
|
+
AUTH_GxKqTnJpYwRzLhBcVfQmNsXeUaPkTdWr
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
Add a suffix:
|
|
471
|
+
|
|
472
|
+
```bash
|
|
473
|
+
python zora.py 32 --suffix "_KEY"
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
Both can be used together:
|
|
477
|
+
|
|
478
|
+
```bash
|
|
479
|
+
python zora.py 32 --prefix "AUTH_" --suffix "_KEY"
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
> Prefixes and suffixes are not random and therefore do not contribute to
|
|
483
|
+
> the calculated entropy.
|
|
484
|
+
|
|
485
|
+
---
|
|
486
|
+
|
|
487
|
+
# Grouping
|
|
488
|
+
|
|
489
|
+
Use `--group` to insert a separator every N characters.
|
|
490
|
+
|
|
491
|
+
For example:
|
|
492
|
+
|
|
493
|
+
```bash
|
|
494
|
+
python zora.py 32 --group 4
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
Output:
|
|
498
|
+
|
|
499
|
+
```text
|
|
500
|
+
GxKq-TnJp-YwRz-LhBc-VfQm-NsXe-UaPk-TdWr
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
The default separator is:
|
|
504
|
+
|
|
505
|
+
```text
|
|
506
|
+
-
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
Use `--sep` to change it:
|
|
510
|
+
|
|
511
|
+
```bash
|
|
512
|
+
python zora.py 32 --group 4 --sep ":"
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
Output:
|
|
516
|
+
|
|
517
|
+
```text
|
|
518
|
+
GxKq:TnJp:YwRz:LhBc:VfQm:NsXe:UaPk:TdWr
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
Grouping only changes the presentation of the key. It does not affect
|
|
522
|
+
entropy.
|
|
523
|
+
|
|
524
|
+
---
|
|
525
|
+
|
|
526
|
+
# File output
|
|
527
|
+
|
|
528
|
+
Use `-o` or `--output` to write generated keys to a file:
|
|
529
|
+
|
|
530
|
+
```bash
|
|
531
|
+
python zora.py 32 -n 10 --output keys.txt
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
The generated keys are written one per line.
|
|
535
|
+
|
|
536
|
+
Example:
|
|
537
|
+
|
|
538
|
+
```text
|
|
539
|
+
GxKqTnJpYwRzLhBcVfQmNsXeUaPkTdWr
|
|
540
|
+
aQmXzPjLtVrNsYkBcWdHgFqAeUxRoZiLp
|
|
541
|
+
...
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
---
|
|
545
|
+
|
|
546
|
+
# Secure generation
|
|
547
|
+
|
|
548
|
+
Zora uses Python's `secrets` module by default.
|
|
549
|
+
|
|
550
|
+
This is the recommended mode when generating authentication tokens,
|
|
551
|
+
API keys, secrets, or other security-sensitive random values.
|
|
552
|
+
|
|
553
|
+
```bash
|
|
554
|
+
python zora.py 32
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
The output will report:
|
|
558
|
+
|
|
559
|
+
```text
|
|
560
|
+
Generator: CSPRNG
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
---
|
|
564
|
+
|
|
565
|
+
# Unsafe / PRNG mode
|
|
566
|
+
|
|
567
|
+
Use:
|
|
568
|
+
|
|
569
|
+
```bash
|
|
570
|
+
python zora.py 32 --unsafe
|
|
571
|
+
```
|
|
572
|
+
|
|
573
|
+
to use Python's normal pseudo-random number generator instead of the
|
|
574
|
+
cryptographically secure generator.
|
|
575
|
+
|
|
576
|
+
Zora will display a warning:
|
|
577
|
+
|
|
578
|
+
```text
|
|
579
|
+
Program will output cryptographically insecure keys.
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
and:
|
|
583
|
+
|
|
584
|
+
```text
|
|
585
|
+
Generator: PRNG
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
This mode exists primarily for testing, reproducibility, benchmarking,
|
|
589
|
+
and experimentation.
|
|
590
|
+
|
|
591
|
+
**Do not use `--unsafe` for real authentication keys or other
|
|
592
|
+
security-sensitive secrets.**
|
|
593
|
+
|
|
594
|
+
---
|
|
595
|
+
|
|
596
|
+
# Seeds
|
|
597
|
+
|
|
598
|
+
Seeds are only allowed with `--unsafe`.
|
|
599
|
+
|
|
600
|
+
This is intentional.
|
|
601
|
+
|
|
602
|
+
The following will fail:
|
|
603
|
+
|
|
604
|
+
```bash
|
|
605
|
+
python zora.py 32 --seed example
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
because Zora's secure generator should not be made deterministic through
|
|
609
|
+
the normal CLI.
|
|
610
|
+
|
|
611
|
+
Instead:
|
|
612
|
+
|
|
613
|
+
```bash
|
|
614
|
+
python zora.py 32 --unsafe --seed example
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
A seed can be useful for testing reproducibility.
|
|
618
|
+
|
|
619
|
+
For example:
|
|
620
|
+
|
|
621
|
+
```bash
|
|
622
|
+
python zora.py 32 --unsafe --seed test
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
will produce the same deterministic sequence when run with the same
|
|
626
|
+
configuration.
|
|
627
|
+
|
|
628
|
+
When generating multiple keys, the PRNG is seeded once before generation
|
|
629
|
+
rather than being reseeded for every key.
|
|
630
|
+
|
|
631
|
+
---
|
|
632
|
+
|
|
633
|
+
# Quiet mode
|
|
634
|
+
|
|
635
|
+
Use `-q` or `--quiet` to suppress non-essential output:
|
|
636
|
+
|
|
637
|
+
```bash
|
|
638
|
+
python zora.py 32 --quiet
|
|
639
|
+
```
|
|
640
|
+
|
|
641
|
+
This is useful when using Zora inside scripts or shell pipelines.
|
|
642
|
+
|
|
643
|
+
For example:
|
|
644
|
+
|
|
645
|
+
```bash
|
|
646
|
+
python zora.py 32 --quiet > key.txt
|
|
647
|
+
```
|
|
648
|
+
|
|
649
|
+
---
|
|
650
|
+
|
|
651
|
+
# Entropy
|
|
652
|
+
|
|
653
|
+
Zora calculates the theoretical entropy of the random portion of the
|
|
654
|
+
key.
|
|
655
|
+
|
|
656
|
+
The formula is:
|
|
657
|
+
|
|
658
|
+
$entropy = length \times \log{_2}{(charset size)}$
|
|
659
|
+
|
|
660
|
+
For example, using 52 possible characters:
|
|
661
|
+
|
|
662
|
+
$32 \times log{_2}\space 52$
|
|
663
|
+
|
|
664
|
+
produces approximately:
|
|
665
|
+
|
|
666
|
+
```text
|
|
667
|
+
182.17 bits
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
The entropy calculation only considers random characters.
|
|
671
|
+
|
|
672
|
+
Known prefixes, suffixes, and grouping separators do not increase the
|
|
673
|
+
entropy.
|
|
674
|
+
|
|
675
|
+
For example:
|
|
676
|
+
|
|
677
|
+
```bash
|
|
678
|
+
python zora.py 32 --prefix "AUTH_"
|
|
679
|
+
```
|
|
680
|
+
|
|
681
|
+
has the same theoretical entropy as:
|
|
682
|
+
|
|
683
|
+
```bash
|
|
684
|
+
python zora.py 32
|
|
685
|
+
```
|
|
686
|
+
|
|
687
|
+
assuming the same charset and length.
|
|
688
|
+
|
|
689
|
+
---
|
|
690
|
+
|
|
691
|
+
# Strength
|
|
692
|
+
|
|
693
|
+
Zora provides a simple entropy-based strength classification.
|
|
694
|
+
|
|
695
|
+
| Entropy | Classification |
|
|
696
|
+
| -----------: | -------------- |
|
|
697
|
+
| `< 40` bits | Very weak |
|
|
698
|
+
| `40–59` bits | Weak |
|
|
699
|
+
| `60–79` bits | Moderate |
|
|
700
|
+
| `80–99` bits | Strong |
|
|
701
|
+
| `100+` bits | Very strong |
|
|
702
|
+
|
|
703
|
+
This is a simple classification rather than a formal security guarantee.
|
|
704
|
+
|
|
705
|
+
A high theoretical entropy value does not make an insecure PRNG
|
|
706
|
+
cryptographically secure.
|
|
707
|
+
|
|
708
|
+
For this reason, Zora explicitly identifies the generator as either:
|
|
709
|
+
|
|
710
|
+
```text
|
|
711
|
+
CSPRNG
|
|
712
|
+
```
|
|
713
|
+
|
|
714
|
+
or:
|
|
715
|
+
|
|
716
|
+
```text
|
|
717
|
+
PRNG
|
|
718
|
+
```
|
|
719
|
+
|
|
720
|
+
---
|
|
721
|
+
|
|
722
|
+
# Example commands
|
|
723
|
+
|
|
724
|
+
### Basic key
|
|
725
|
+
|
|
726
|
+
```bash
|
|
727
|
+
python zora.py 32
|
|
728
|
+
```
|
|
729
|
+
|
|
730
|
+
### Digits only
|
|
731
|
+
|
|
732
|
+
```bash
|
|
733
|
+
python zora.py 32 --charset @digits
|
|
734
|
+
```
|
|
735
|
+
|
|
736
|
+
### Lowercase only
|
|
737
|
+
|
|
738
|
+
```bash
|
|
739
|
+
python zora.py 32 --charset @lower
|
|
740
|
+
```
|
|
741
|
+
|
|
742
|
+
### Uppercase only
|
|
743
|
+
|
|
744
|
+
```bash
|
|
745
|
+
python zora.py 32 --charset @upper
|
|
746
|
+
```
|
|
747
|
+
|
|
748
|
+
### Alphanumeric
|
|
749
|
+
|
|
750
|
+
```bash
|
|
751
|
+
python zora.py 32 --charset @letters@digits
|
|
752
|
+
```
|
|
753
|
+
|
|
754
|
+
### Hexadecimal
|
|
755
|
+
|
|
756
|
+
```bash
|
|
757
|
+
python zora.py 32 --charset @hex
|
|
758
|
+
```
|
|
759
|
+
|
|
760
|
+
### Hexadecimal plus custom characters
|
|
761
|
+
|
|
762
|
+
```bash
|
|
763
|
+
python zora.py 32 --charset @hexXYZ
|
|
764
|
+
```
|
|
765
|
+
|
|
766
|
+
### Uppercase, lowercase and digits
|
|
767
|
+
|
|
768
|
+
```bash
|
|
769
|
+
python zora.py 32 --charset @upper@lower@digits
|
|
770
|
+
```
|
|
771
|
+
|
|
772
|
+
### Symbols
|
|
773
|
+
|
|
774
|
+
```bash
|
|
775
|
+
python zora.py 32 --charset @special
|
|
776
|
+
```
|
|
777
|
+
|
|
778
|
+
### Group the output
|
|
779
|
+
|
|
780
|
+
```bash
|
|
781
|
+
python zora.py 32 --group 4
|
|
782
|
+
```
|
|
783
|
+
|
|
784
|
+
### Custom separator
|
|
785
|
+
|
|
786
|
+
```bash
|
|
787
|
+
python zora.py 32 --group 4 --sep ":"
|
|
788
|
+
```
|
|
789
|
+
|
|
790
|
+
### Generate multiple keys
|
|
791
|
+
|
|
792
|
+
```bash
|
|
793
|
+
python zora.py 32 -n 10
|
|
794
|
+
```
|
|
795
|
+
|
|
796
|
+
### Save to a file
|
|
797
|
+
|
|
798
|
+
```bash
|
|
799
|
+
python zora.py 32 -n 100 -o keys.txt
|
|
800
|
+
```
|
|
801
|
+
|
|
802
|
+
### Prefix
|
|
803
|
+
|
|
804
|
+
```bash
|
|
805
|
+
python zora.py 32 --prefix "AUTH_"
|
|
806
|
+
```
|
|
807
|
+
|
|
808
|
+
### Secure generation
|
|
809
|
+
|
|
810
|
+
```bash
|
|
811
|
+
python zora.py 32
|
|
812
|
+
```
|
|
813
|
+
|
|
814
|
+
### Reproducible testing
|
|
815
|
+
|
|
816
|
+
```bash
|
|
817
|
+
python zora.py 32 --unsafe --seed test
|
|
818
|
+
```
|
|
819
|
+
|
|
820
|
+
### Quiet output
|
|
821
|
+
|
|
822
|
+
```bash
|
|
823
|
+
python zora.py 32 --quiet
|
|
824
|
+
```
|
|
825
|
+
|
|
826
|
+
---
|
|
827
|
+
|
|
828
|
+
# Security
|
|
829
|
+
|
|
830
|
+
Zora is designed to make secure random generation the default.
|
|
831
|
+
|
|
832
|
+
The default generator uses Python's `secrets` module rather than
|
|
833
|
+
Python's standard `random` module.
|
|
834
|
+
|
|
835
|
+
The `--unsafe` option deliberately switches to a normal pseudo-random
|
|
836
|
+
number generator.
|
|
837
|
+
|
|
838
|
+
This distinction is important:
|
|
839
|
+
|
|
840
|
+
```text
|
|
841
|
+
Default
|
|
842
|
+
↓
|
|
843
|
+
secrets
|
|
844
|
+
↓
|
|
845
|
+
CSPRNG
|
|
846
|
+
↓
|
|
847
|
+
Suitable for security-sensitive random values
|
|
848
|
+
```
|
|
849
|
+
|
|
850
|
+
versus:
|
|
851
|
+
|
|
852
|
+
```text
|
|
853
|
+
--unsafe
|
|
854
|
+
↓
|
|
855
|
+
random
|
|
856
|
+
↓
|
|
857
|
+
PRNG
|
|
858
|
+
↓
|
|
859
|
+
Not suitable for security-sensitive values
|
|
860
|
+
```
|
|
861
|
+
|
|
862
|
+
Do not use `--unsafe` generated values for:
|
|
863
|
+
|
|
864
|
+
* Authentication credentials
|
|
865
|
+
* Password reset tokens
|
|
866
|
+
* Session tokens
|
|
867
|
+
* API secrets
|
|
868
|
+
* Encryption keys
|
|
869
|
+
* Other security-sensitive secrets
|
|
870
|
+
|
|
871
|
+
unless you specifically understand the security implications.
|
|
872
|
+
|
|
873
|
+
---
|
|
874
|
+
|
|
875
|
+
# Important entropy note
|
|
876
|
+
|
|
877
|
+
The entropy reported by Zora describes the size of the theoretical
|
|
878
|
+
random output space.
|
|
879
|
+
|
|
880
|
+
For example, a 32-character key selected uniformly from 62 possible
|
|
881
|
+
characters has:
|
|
882
|
+
|
|
883
|
+
$32 \times log{_2}\space 62$
|
|
884
|
+
|
|
885
|
+
bits of theoretical entropy.
|
|
886
|
+
|
|
887
|
+
However, entropy alone does not prove that a generator is secure.
|
|
888
|
+
|
|
889
|
+
For example:
|
|
890
|
+
|
|
891
|
+
```bash
|
|
892
|
+
python zora.py 32 --unsafe
|
|
893
|
+
```
|
|
894
|
+
|
|
895
|
+
can still report a high entropy value because the theoretical output
|
|
896
|
+
space is large.
|
|
897
|
+
|
|
898
|
+
The generator is nevertheless explicitly marked:
|
|
899
|
+
|
|
900
|
+
```text
|
|
901
|
+
Generator: PRNG
|
|
902
|
+
```
|
|
903
|
+
|
|
904
|
+
and the entropy/strength display is visually marked when `--unsafe` is
|
|
905
|
+
used.
|
|
906
|
+
|
|
907
|
+
---
|
|
908
|
+
|
|
909
|
+
# Development
|
|
910
|
+
|
|
911
|
+
Clone the repository:
|
|
912
|
+
|
|
913
|
+
```bash
|
|
914
|
+
git clone https://github.com/zscopuv/Zora.git
|
|
915
|
+
cd Zora
|
|
916
|
+
```
|
|
917
|
+
|
|
918
|
+
Install dependencies:
|
|
919
|
+
|
|
920
|
+
```bash
|
|
921
|
+
pip install -r requirements.txt
|
|
922
|
+
```
|
|
923
|
+
|
|
924
|
+
Run:
|
|
925
|
+
|
|
926
|
+
```bash
|
|
927
|
+
python zora.py 32
|
|
928
|
+
```
|
|
929
|
+
|
|
930
|
+
---
|
|
931
|
+
|
|
932
|
+
# Project structure
|
|
933
|
+
|
|
934
|
+
A minimal installation currently looks like:
|
|
935
|
+
|
|
936
|
+
```text
|
|
937
|
+
Zora/
|
|
938
|
+
├── zora.py
|
|
939
|
+
├── zora.jpg
|
|
940
|
+
├── LICENSE
|
|
941
|
+
├── README.md
|
|
942
|
+
└── requirements.txt
|
|
943
|
+
```
|
|
944
|
+
|
|
945
|
+
Future versions may introduce a package structure and automated tests.
|
|
946
|
+
|
|
947
|
+
---
|
|
948
|
+
|
|
949
|
+
# Roadmap
|
|
950
|
+
|
|
951
|
+
Possible future improvements include:
|
|
952
|
+
|
|
953
|
+
* [ ] Automated test suite
|
|
954
|
+
* [ ] More charset presets
|
|
955
|
+
* [ ] Better charset parsing errors
|
|
956
|
+
* [ ] Configuration files
|
|
957
|
+
* [ ] Packaging with `pyproject.toml`
|
|
958
|
+
* [ ] Installation through `pip`
|
|
959
|
+
* [ ] Shell completion
|
|
960
|
+
* [ ] More output formats
|
|
961
|
+
* [ ] Benchmarking mode
|
|
962
|
+
* [ ] Improved documentation
|
|
963
|
+
* [ ] Cross-platform terminal improvements
|
|
964
|
+
* [ ] API/library usage
|
|
965
|
+
* [ ] More extensive security testing
|
|
966
|
+
|
|
967
|
+
The roadmap is subject to change.
|
|
968
|
+
|
|
969
|
+
---
|
|
970
|
+
|
|
971
|
+
# Versioning
|
|
972
|
+
|
|
973
|
+
Zora currently follows semantic versioning:
|
|
974
|
+
|
|
975
|
+
```text
|
|
976
|
+
MAJOR.MINOR.PATCH
|
|
977
|
+
```
|
|
978
|
+
|
|
979
|
+
For example:
|
|
980
|
+
|
|
981
|
+
```text
|
|
982
|
+
v0.1.0
|
|
983
|
+
```
|
|
984
|
+
|
|
985
|
+
The `0.x` versions indicate that the CLI and features may still change
|
|
986
|
+
before the first stable `1.0.0` release.
|
|
987
|
+
|
|
988
|
+
---
|
|
989
|
+
|
|
990
|
+
# Contributing
|
|
991
|
+
|
|
992
|
+
Contributions, bug reports, feature requests, and suggestions are
|
|
993
|
+
welcome.
|
|
994
|
+
|
|
995
|
+
Before submitting a change:
|
|
996
|
+
|
|
997
|
+
1. Make sure the program still runs.
|
|
998
|
+
2. Test the affected CLI options.
|
|
999
|
+
3. Avoid breaking existing behavior unless the change is intentional.
|
|
1000
|
+
4. Update the documentation when adding or changing an option.
|
|
1001
|
+
|
|
1002
|
+
---
|
|
1003
|
+
|
|
1004
|
+
# License
|
|
1005
|
+
|
|
1006
|
+
This project is licensed under the MIT License.
|
|
1007
|
+
|
|
1008
|
+
See [`LICENSE`](LICENSE) for the full license text.
|
|
1009
|
+
|
|
1010
|
+
---
|
|
1011
|
+
|
|
1012
|
+
# Disclaimer
|
|
1013
|
+
|
|
1014
|
+
Zora is provided as-is.
|
|
1015
|
+
|
|
1016
|
+
While Zora uses a cryptographically secure random generator by default,
|
|
1017
|
+
the security of a system depends on how generated values are stored,
|
|
1018
|
+
transmitted, and used.
|
|
1019
|
+
|
|
1020
|
+
Always evaluate the complete security design of the application in which
|
|
1021
|
+
a generated key or token is used.
|