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.
@@ -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
+ # ![Logo](zora.jpg)
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.