Early release (
v0.2.1)
Zora is a command-line tool for generating random keys using Python's
cryptographically secure secrets module by default.
It supports customizable character sets, composable charset presets, prefixes, suffixes, grouping, multiple output formats, file output, entropy estimation, benchmarking, and an optional deterministic PRNG mode.
Features
- 🔐 Cryptographically secure generation by default
- ⚠️ Optional insecure PRNG mode with
--unsafe - 🎲 Deterministic generation with
--seedin unsafe mode - 🔤 Custom character sets
- 🧩 Composable charset presets such as
@letters@digits - ⚡ Fast charset shorthand with
-x - 🔢 28 built-in charset presets
- ➕ Add custom characters to presets
- 📏 Configurable key length
- 📦 Generate multiple keys at once
- 🔗 Add prefixes and suffixes
- 📐 Group keys with custom separators
- 💾 Write generated keys to a file
- 📤 Multiple output formats: Text, JSON, CSV, XML, YAML
- 📊 Calculate theoretical entropy
- 💪 Estimate key strength from entropy
- ⏱️ Display generation time
- 🏁 Benchmark key generation
- 🤫 Quiet mode for scripting
- 📋 Charset preset listing
- 🔍 Charset and argument validation
- ℹ️ Display the installed version with
--version
Installation
Requirements
Python 3.9 or newer is recommended.
Install Zora from PyPI:
pip install zora-cli
Run Zora:
zora 32
Optional YAML support
YAML output requires PyYAML:
pip install pyyaml
Usage
Basic usage:
zora LENGTH [OPTIONS]
For example:
zora 32
Example output:
GxKqTnJpYwRzLhBcVfQmNsXeUaPkTdWr
Timer: 13ms elapsed
Charset: 52
Entropy: 182.41 bits
Strength: Very strong
Generator: CSPRNG
Arguments
length
The length of the random portion of the generated key.
zora 32
The value must be greater than 0.
--version
Display the currently installed Zora version:
zora --version
Example:
zora 0.1.2
--charset / -x
Select the character set used to generate keys.
The default charset is:
@letters
Long form:
zora 32 --charset @digits
Short form:
zora 32 -x @digits
The -x option is provided as a convenient shorthand for faster charset selection.
Zora supports both predefined charset presets and literal characters.
Charset presets
Use:
zora --charset-list
to display all available presets.
Basic
@@→ literal@
| Preset | Characters |
|---|---|
@digits |
0-9 |
@letters |
a-zA-Z |
@lower |
a-z |
@upper |
A-Z |
@special |
Punctuation and symbols |
Numeric
| Preset | Characters |
|---|---|
@bin |
01 |
@oct |
01234567 |
@hex |
0123456789ABCDEF |
@lhex |
0123456789abcdef |
@allhex |
0123456789ABCDEFabcdef |
URL / filename friendly
| Preset | Characters |
|---|---|
@url |
URL-friendly characters |
@urlsafe |
URL-safe alphanumeric characters |
@filename |
Filename-safe characters |
Human-friendly
These presets avoid characters that can easily be confused with one another.
| Preset | Description |
|---|---|
@lowersafe |
Lowercase without l |
@uppersafe |
Uppercase without I and O |
@digitssafe |
Digits without 0 and 1 |
Base encodings
| Preset | Description |
|---|---|
@base32 |
Uppercase Base32 alphabet |
@base32x |
Lowercase Base32 alphabet |
@base36 |
Uppercase Base36 alphabet |
@base36x |
Lowercase Base36 alphabet |
@base62 |
Base62 alphabet |
Base64
| Preset | Description |
|---|---|
@base64 |
Standard Base64 alphabet |
@base64url |
URL-safe Base64 alphabet |
Symbols
| Preset | Characters |
|---|---|
@symbols |
Punctuation and symbols |
@brackets |
()[]{}<> |
@quotes |
Quote characters |
@math |
Common mathematical symbols |
Combining presets
Presets can be combined:
zora 32 --charset @letters@digits
This creates an alphanumeric character set.
Multiple presets can also be combined:
zora 32 --charset @upper@lower@digits
Duplicate characters are automatically removed.
For example:
@letters@upper
does not contain uppercase characters twice.
The short -x form can be used as well:
zora 32 -x @upper@lower@digits
Custom characters
Literal characters can be included alongside presets.
For example:
zora 32 --charset @hexXYZ
This means:
@hex + X + Y + Z
Another example:
zora 32 --charset XYZ@hex
means:
X + Y + Z + @hex
This allows arbitrary character sets without requiring a new preset.
--charset-list
Display all available charset presets:
zora --charset-list
The output includes the preset name and its characters.
Example:
Available charsets:
@digits = 0123456789
@letters = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
@lower = abcdefghijklmnopqrstuvwxyz
@upper = ABCDEFGHIJKLMNOPQRSTUVWXYZ
...
Use as:
zora --charset @digits
zora --charset @letters@digits
zora --charset @hexXYZ
This mode exits immediately after displaying the available presets.
Multiple keys
Use -n or --count to generate multiple keys:
zora 32 --count 10
or:
zora 32 -n 10
Each key is generated independently.
When using the secure default generator, each key is generated using the cryptographically secure random generator.
Prefixes and suffixes
Add a prefix:
zora 32 --prefix "AUTH_"
Example:
AUTH_GxKqTnJpYwRzLhBcVfQmNsXeUaPkTdWr
Add a suffix:
zora 32 --suffix "_KEY"
Both can be used together:
zora 32 --prefix "AUTH_" --suffix "_KEY"
Prefixes and suffixes are not random and therefore do not contribute to the calculated entropy.
Grouping
Use --group to insert a separator every N characters.
For example:
zora 32 --group 4
Output:
GxKq-TnJp-YwRz-LhBc-VfQm-NsXe-UaPk-TdWr
The default separator is:
-
Use --sep to change it:
zora 32 --group 4 --sep ":"
Output:
GxKq:TnJp:YwRz:LhBc:VfQm:NsXe:UaPk:TdWr
Grouping only changes the presentation of the key. It does not affect entropy.
Output formats
Zora supports multiple output formats through --format.
Available formats:
textjsoncsvxmlyml
The default format is text.
Text
zora 32 --format text
This is the default output format.
JSON
zora 32 -n 3 --format json
Example:
{
"keys": [
"GxKqTnJpYwRzLhBcVfQmNsXeUaPkTdWr",
"...",
"..."
]
}
CSV
zora 32 -n 3 --format csv
The generated CSV contains a key column.
XML
zora 32 -n 3 --format xml
YAML
zora 32 -n 3 --format yml
YAML output requires PyYAML:
pip install pyyaml
File output
Use -o or --output to write generated output to a file:
zora 32 -n 10 --output keys.txt
The output format can be selected independently:
zora 32 -n 10 --format json -o keys.json
zora 32 -n 10 --format csv -o keys.csv
Generated files use UTF-8 encoding.
Text-based CLI output uses a conventional final newline.
Secure generation
Zora uses Python's secrets module by default.
This is the recommended mode when generating authentication tokens, API keys, secrets, or other security-sensitive random values.
zora 32
The output will report:
Generator: CSPRNG
Unsafe / PRNG mode
Use:
zora 32 --unsafe
to use Python's normal pseudo-random number generator instead of the cryptographically secure generator.
Zora will display a warning:
Program will output cryptographically insecure keys.
and:
Generator: PRNG
This mode exists primarily for testing, reproducibility, benchmarking, and experimentation.
Do not use --unsafe for real authentication keys or other
security-sensitive secrets.
Seeds
Seeds are only allowed with --unsafe.
This is intentional.
The following will fail:
zora 32 --seed example
because Zora's secure generator should not be made deterministic through the normal CLI.
Instead:
zora 32 --unsafe --seed example
A seed can be useful for testing reproducibility.
For example:
zora 32 --unsafe --seed test
will produce the same deterministic sequence when run with the same configuration.
When generating multiple keys, the PRNG is seeded once before generation rather than being reseeded for every key.
Benchmarking
Use --benchmark to benchmark key generation:
zora 32 --benchmark
The benchmark reports:
- Generator
- Key length
- Number of keys
- Charset size
- Total characters generated
- Keys per second
- Characters per second
Example:
Zora Benchmark
────────────────────────────────
Generator: CSPRNG
Length: 32
Count: 1
Charset: 52
Characters: 32
Keys/sec: ...
Characters/sec: ...
Benchmarking does not produce normal key output.
The benchmark respects --unsafe, --seed, --count, and the selected
charset.
Quiet mode
Use -q or --quiet to suppress non-essential output:
zora 32 --quiet
This is useful when using Zora inside scripts or shell pipelines.
For example:
zora 32 --quiet > key.txt
Quiet mode suppresses the timer, entropy, strength, generator information, and update notification.
Entropy
Zora calculates the theoretical entropy of the random portion of the key.
The formula is:
entropy = length × log₂(charset size)
For example, using 52 possible characters:
32 × log₂(52)
produces approximately:
182.41 bits
The entropy calculation only considers random characters.
Known prefixes, suffixes, and grouping separators do not increase the entropy.
For example:
zora 32 --prefix "AUTH_"
has the same theoretical entropy as:
zora 32
assuming the same charset and length.
Strength
Zora provides a simple entropy-based strength classification.
| Entropy | Classification |
|---|---|
< 40 bits |
Very weak |
40–59 bits |
Weak |
60–79 bits |
Moderate |
80–99 bits |
Strong |
100+ bits |
Very strong |
This is a simple classification rather than a formal security guarantee.
A high theoretical entropy value does not make an insecure PRNG cryptographically secure.
For this reason, Zora explicitly identifies the generator as either:
CSPRNG
or:
PRNG
Argument validation
Zora validates command-line arguments before generating keys.
Examples of invalid arguments include:
- A key length of
0or less - A key length missing when generation is requested
- A
--groupvalue greater than the key length - Using
--seedwithout--unsafe - An unknown charset preset
- An empty final charset
- A charset containing fewer than two unique characters
Invalid arguments result in a clear command-line error instead of attempting to generate invalid output.
Example commands
Basic key
zora 32
Digits only
zora 32 -x @digits
Lowercase only
zora 32 -x @lower
Uppercase only
zora 32 -x @upper
Alphanumeric
zora 32 -x @letters@digits
Hexadecimal
zora 32 -x @hex
Hexadecimal plus custom characters
zora 32 -x @hexXYZ
Uppercase, lowercase and digits
zora 32 -x @upper@lower@digits
Human-friendly digits
zora 32 -x @digitssafe
Symbols
zora 32 -x @symbols
Group the output
zora 32 --group 4
Custom separator
zora 32 --group 4 --sep ":"
Generate multiple keys
zora 32 -n 10
Save to a file
zora 32 -n 100 -o keys.txt
JSON output
zora 32 -n 10 --format json
Benchmark
zora 32 --benchmark
Show available charsets
zora --charset-list
Show version
zora --version
Prefix
zora 32 --prefix "AUTH_"
Secure generation
zora 32
Reproducible testing
zora 32 --unsafe --seed test
Quiet output
zora 32 --quiet
Security
Zora is designed to make secure random generation the default.
The default generator uses Python's secrets module rather than
Python's standard random module.
The --unsafe option deliberately switches to a normal pseudo-random
number generator.
This distinction is important:
Default
↓
secrets
↓
CSPRNG
↓
Suitable for security-sensitive random values
versus:
--unsafe
↓
random
↓
PRNG
↓
Not suitable for security-sensitive values
Do not use --unsafe generated values for:
- Authentication credentials
- Password reset tokens
- Session tokens
- API secrets
- Encryption keys
- Other security-sensitive secrets
unless you specifically understand the security implications.
Important entropy note
The entropy reported by Zora describes the size of the theoretical random output space.
For example, a 32-character key selected uniformly from 62 possible characters has:
32 × log₂(62)
bits of theoretical entropy.
However, entropy alone does not prove that a generator is secure.
For example:
zora 32 --unsafe
can still report a high entropy value because the theoretical output space is large.
The generator is nevertheless explicitly marked:
Generator: PRNG
and the entropy and strength display is visually marked when --unsafe
is used.
Development
Clone the repository:
git clone https://github.com/zscopuv/Zora.git
cd Zora
Install dependencies:
pip install -r requirements.txt
Run:
zora 32
For YAML output, install PyYAML:
pip install pyyaml
Roadmap
Possible future improvements include:
- More charset presets
- Improved documentation
- Installation through
pip - Packaging with
pyproject.toml - Better charset parsing errors
- Multiple output formats
- Benchmarking mode
- Version information
- Argument validation
- Automated test suite
- Configuration files
- Shell completion
- Cross-platform terminal improvements
- API/library usage
- More extensive security testing
The roadmap is subject to change.
Versioning
Zora currently follows semantic versioning:
MAJOR.MINOR.PATCH
For example:
v0.1.3
The 0.x versions indicate that the CLI and features may still change
before the first stable 1.0.0 release.
Contributing
Contributions, bug reports, feature requests, and suggestions are welcome.
Before submitting a change:
- Make sure the program still runs.
- Test the affected CLI options.
- Avoid breaking existing behavior unless the change is intentional.
- Update the documentation when adding or changing an option.
License
This project is licensed under the MIT License.
See LICENSE for the full license text.
Disclaimer
Zora is provided as-is.
While Zora uses a cryptographically secure random generator by default, the security of a system depends on how generated values are stored, transmitted, and used.
Always evaluate the complete security design of the application in which a generated key or token is used.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file zora_cli-0.2.1.tar.gz.
File metadata
- Download URL: zora_cli-0.2.1.tar.gz
- Upload date:
- Size: 26.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
97af1d75fd3785024a7703e091e8f4836c515fe156f8dc14590383bb08903665
|
|
| MD5 |
081735f10977310a64a505df2d7f13f5
|
|
| BLAKE2b-256 |
40a2ea441df7461e893b4a2f76b2724dc9a5082f3f709c4a33b10177c81b344a
|
Provenance
The following attestation bundles were made for zora_cli-0.2.1.tar.gz:
Publisher:
publish.yml on zscopuv/zora-cli
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
zora_cli-0.2.1.tar.gz -
Subject digest:
97af1d75fd3785024a7703e091e8f4836c515fe156f8dc14590383bb08903665 - Sigstore transparency entry: 2821752889
- Sigstore integration time:
-
Permalink:
zscopuv/zora-cli@261ca57d9effc004122664cbb625c3c4c55e9043 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/zscopuv
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@261ca57d9effc004122664cbb625c3c4c55e9043 -
Trigger Event:
release
-
Statement type:
File details
Details for the file zora_cli-0.2.1-py3-none-any.whl.
File metadata
- Download URL: zora_cli-0.2.1-py3-none-any.whl
- Upload date:
- Size: 17.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8c64585f202c0b56e573df5641f248bd0a3fa4778f9cb2f42fef20ca8b3c791a
|
|
| MD5 |
abd96a089dc37d7ef82ddd9b72e0d540
|
|
| BLAKE2b-256 |
36890cecfa5c74634480eca001eab54ca5ae1fe00cfcd82bc5b2ba5de3c3a58b
|
Provenance
The following attestation bundles were made for zora_cli-0.2.1-py3-none-any.whl:
Publisher:
publish.yml on zscopuv/zora-cli
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
zora_cli-0.2.1-py3-none-any.whl -
Subject digest:
8c64585f202c0b56e573df5641f248bd0a3fa4778f9cb2f42fef20ca8b3c791a - Sigstore transparency entry: 2821752921
- Sigstore integration time:
-
Permalink:
zscopuv/zora-cli@261ca57d9effc004122664cbb625c3c4c55e9043 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/zscopuv
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@261ca57d9effc004122664cbb625c3c4c55e9043 -
Trigger Event:
release
-
Statement type: