Skip to main content

IsMyPwdSafe - The only password audit that doesn't spy on you.

IsMyPwdSafe full audit output

A privacy-first command-line password auditor.
Entropy math, pattern detection and breach lookup - all from your terminal.

Install from PyPI     PyPI version

PyPI Python 3.8+ License: MIT Platforms PRs Welcome Runtime deps Network calls

Read this before you run it: imps "your-password" puts the password in your shell history, terminal scrollback and any log your terminal writes to. If you need the password out of history, prefix the command with a space (requires HISTCONTROL=ignorespace in bash/zsh), clear the history after or wait for the interactive mode on the roadmap. This tool is an audit utility - it is not a password manager. Do not use it as one.

Project status - actively developed. IsMyPwdSafe is under active development. A --offline flag that skips both network calls (HIBP and the GitHub version check) is planned for the next release, so a fully offline audit will be a single flag instead of a firewall rule. Additional flags are in progress. If you have ideas, want to report a bug or want to contribute, open an issue or a pull request. See Roadmap and Contributing.


Quick Start

1. Install

The only runtime dependency is requests. pipx gives you a global imps command in an isolated venv:

pipx install ismypwdsafe

pip works too if you prefer a shared environment:

pip install ismypwdsafe

From source, or without installing at all:

git clone https://github.com/Roma476/IsMyPwdSafe.git
cd IsMyPwdSafe
pip install .
# or
python -m ismypwdsafe.main "correct-horse-battery-staple"

2. Run an audit

imps "correct-horse-battery-staple"
IsMyPwdSafe full audit output

The engine computes the charset, the number of possible combinations, the estimated time to crack on four hardware profiles and the HaveIBeenPwned result. All in one pass, all locally apart from the two HTTP requests listed below.

3. Run an audit on a known-weak password

imps "password"

Two independent things fire here. The pattern engine matches password against the top-150 dictionary and caps the score at 30. The HaveIBeenPwned lookup finds the password in breach data and caps at 10. The final result is a WEAK 10/100 with two separate warnings in the DARKWEB SCANNER panel and the SEARCH SPACE panel:

IsMyPwdSafe pattern and search space warning IsMyPwdSafe darkweb scanner warning

4. Mask the password in the output

If you are auditing on a shared screen or a recording:

imps -M "MySecretPassword!"
IsMyPwdSafe masked output

The password appears as ************ in the INPUT METRICS panel. Everything else is computed normally.

(back to top)


What IsMyPwdSafe can do

Feature Description
Entropy estimation Charset detection and C^L combination count with log10 fallback for large search spaces
Top-150 dictionary Substring match against the 150 most-used passwords, with leet-speak normalization
QWERTY walk detection Real keyboard coordinate model catching qwerty, 1qaz2wsx, zxcvbn and similar walks
Common year detection Flags 4-digit runs in the 1900-2050 range
Character repetition Flags three or more identical consecutive characters
HaveIBeenPwned range lookup k-anonymity breach check; only a 5-character SHA-1 prefix leaves the machine
Hardware resistance graph Estimated time-to-crack on PC, server, GPU rig and cluster
Privacy mask mode -M / --Mask replaces the password with asterisks in all output
Skip update check --no-update-check disables the single GitHub request at startup

(back to top)


Use Cases

  • Personal audit - check your own passwords without pasting them into an unknown web form. Useful before migrating to a password manager.
  • Security training - show colleagues the actual difference between Summer2024! and correct-horse-battery-staple in entropy numbers and time-to-crack instead of vague "strong/weak" labels.
  • Assessing leaked credentials - when a plaintext password turns up in a dump or during a CTF, check how strong it actually is before deciding whether to report it as critical.
  • Pre-deployment checks - quick scan of default passwords or example strings before they ship in a config file.

(back to top)


Detection engine

The score is not a linear function of length. It combines a mathematical entropy estimate with a set of pattern rules that catch the cases where entropy is misleading - Password123 has non-trivial entropy on paper but is trivially guessable because the pattern is known.

Charset and entropy

Each character contributes to the charset once:

Class Contribution
Digits 0-9 +10
Lowercase a-z +26
Uppercase A-Z +26
Printable ASCII symbols +33

Non-ASCII characters do not contribute to the estimate - the search space is modelled over printable ASCII only. Total combinations are C^L and entropy in base 10 is L * log10(C).

For large search spaces the raw C^L overflows the display width, so the engine switches to log-space representation (10^x). The switch is decided by must_use_log(C, L):

Condition Behaviour
C > 95 and L >= 3 log-space
C ∈ {62, 63} and L >= 5 log-space
Otherwise L >= 4 → log-space

That is why some outputs show 10^39.65 instead of a full integer - it is precise and it fits the panel.

Rule 1: Top-150 dictionary

Substring match against the top-150 most-used passwords. Before matching, the input is lowercased and normalized through a leet-speak translation table:

@ → a    4 → a    3 → e    0 → o    1 → i
! → i    $ → s    5 → s    7 → t    8 → b

So P@ssw0rd becomes password and is caught. MyPassword123 also matches because password123 is a substring of the normalized input. This is the most aggressive rule - it is why so many "clever" passwords still score low.

Rule 2: QWERTY spatial walk

Each key is mapped to a (row, column) coordinate on a real QWERTY keyboard:

row 0:  1 2 3 4 5 6 7 8 9 0
row 1:  q w e r t y u i o p
row 2:  a s d f g h j k l
row 3:  z x c v b n m

The engine looks for at least 4 consecutive keys moving in the same direction - horizontal, vertical or diagonal. When it finds a run, the password gets flagged. This catches the entire family of keyboard walks that look random to a human but are not:

imps "qwertyuiop"    # horizontal walk
imps "1qaz2wsx"      # diagonal walk
imps "mnbvcxz"       # horizontal reverse walk
imps "1qaz"          # vertical walk

Rule 3: Common year

Scans for a 4-digit run in the 1900-2050 range. MyPassword2024 and Summer1990! both trip this rule even if the surrounding text is clean. This is not a hard match against a list of years - it catches any 4-digit number in the plausible-year range, which is the pattern most people add to a base word when a site forces a "number" requirement.

Rule 4: Character repetition

Any three or more identical consecutive characters. Catches aaa, 111, ... and the family of password!!! variants. Padding is not entropy.

Scoring

base_score = min(100, max(0, log10_value * 5))

if pattern_detected:    base_score = min(base_score, 30)
if pwned_count > 0:     base_score = min(base_score, 10)
Score Rating
0-9 WEAK (pwned)
10-29 WEAK (pattern)
30-49 WEAK
50-69 MEDIUM
70-100 STRONG

The score is capped, not weighted. A single pattern match is treated as a binary event because in practice, once one obvious pattern exists, the rest of the string is no longer the bottleneck - the attacker is running a dictionary or a walk generator, not a brute-force sweep.

(back to top)


Privacy and network behavior

The tool makes two outbound HTTP requests and no others.

1. HaveIBeenPwned Range API

The plaintext password and the full SHA-1 hash never leave the machine. Only a 5-character prefix is transmitted, following the k-anonymity model recommended by HIBP and used by Firefox, 1Password and Bitwarden:

sha1    = SHA1(password)
prefix  = sha1[:5].upper()
suffix  = sha1[5:].upper()

GET https://api.pwnedpasswords.com/range/{prefix}
  → server returns ~800 candidate suffixes
  → local match of `suffix` against the response
  • Transmitted: the 5-character SHA-1 prefix.
  • Not transmitted: plaintext password, full hash, length, character composition, any IP-linked identifier.
  • Timeout: 5 seconds.
  • On failure: the DARKWEB panel shows a warning and the score is computed without the breach cap. The rest of the audit runs normally.

2. GitHub version check

A single GET to raw.githubusercontent.com/Roma476/IsMyPwdSafe/main/version.txt at startup. No identifier, no analytics, no telemetry. It exists solely to warn if a newer version is available. 1.5-second timeout, silent failure.

Disable with --no-update-check.

Skipping network calls

Today the two requests are controlled separately:

imps --no-update-check "your-password"    # skips the GitHub request

A --offline flag that disables both requests in a single switch is in progress and will land in the next release. Until then, a fully air-gapped run requires blocking api.pwnedpasswords.com and raw.githubusercontent.com at the firewall; the audit still works minus the DARKWEB panel.

What the tool does not do

  • No telemetry, no analytics, no crash reporting
  • No account, no email, no local history of past audits
  • No file writes (no logs, no cache, no config on first run)

(back to top)


Known limitations

  • Shell history. imps "pass" ends up in bash/zsh history, terminal scrollback and any log the terminal writes to. Workaround: prefix the command with a space (requires HISTCONTROL=ignorespace) or clear history afterwards. An interactive mode that reads from stdin without echoing is on the roadmap.
  • Two network calls still happen by default. --no-update-check only disables the GitHub request. Disabling the HIBP request currently requires firewall rules; the --offline flag on the roadmap will cover both.
  • ASCII only. The charset is estimated over printable ASCII. Non-ASCII passwords are underestimated in entropy.
  • Finite pattern list. Top-150 plus four structural rules. An uncommon password is not automatically strong - it is only not obviously weak.
  • Crack times are theoretical. They assume a constant hash rate on a given hardware profile. They do not model rainbow tables, targeted dictionaries, GPU-specific optimizations or side channels.
  • DARKWEB depends on HIBP. If the API changes behaviour the panel reports it, but the tool does not update itself.
  • No automated test suite yet. Manual checks are documented in Checks. The roadmap includes a unittest suite and a GitHub Actions workflow.

(back to top)


Checks

# Minimal run
imps "test"

# Strong password, no pattern
imps "correct-horse-battery-staple"

# Walk pattern - should show pattern warning
imps "qwertyuiop"

# Known breach - should show red alert in the DARKWEB SCANNER
imps "123456"

# Mask mode
imps -M "password"

# Skip update check
imps --no-update-check "password"

(back to top)


Project layout

IsMyPwdSafe/
├── ismypwdsafe/
│   ├── __init__.py
│   └── main.py          # CLI, ~700 lines, single file
├── docs/screenshots/    # README screenshots
├── .gitignore
├── LICENSE              # MIT
├── pyproject.toml
├── version.txt
└── README.md

The CLI is a single file by design. It can be read end-to-end in one session and copied to any machine to run with python main.py "password" without installation.

(back to top)


Roadmap

Actively in progress, in rough order of priority:

  • --offline flag - skips both the HIBP and the GitHub requests in a single switch, so a fully offline audit does not require firewall rules.
  • --json output - machine-readable audit result for scripting and CI pipelines.
  • --quiet mode - exit code only, useful in pre-commit hooks and pipelines.
  • Interactive / stdin mode - read the password without echoing it and without putting it in shell history.
  • Test suite and CI - unittest coverage for the entropy engine, the pattern rules and the score caps, plus a GitHub Actions workflow on 3.8 / 3.10 / 3.12.
  • Expanded pattern dictionary - the top-150 list is a starting point, not the endpoint.

Out of scope by design: password storage, account systems, cloud sync. IsMyPwdSafe is an audit tool, not a password manager.

(back to top)


Contributing

Contributions are welcome. Bug reports, feature requests and pull requests all help.

If you want to contribute but the codebase is new to you, open an issue first and describe what you would like to do - new pattern rules, additional hardware profiles in the resistance graph and new flags are all good entry points. Nothing here is locked in.

git clone https://github.com/YOUR-USERNAME/IsMyPwdSafe.git
cd IsMyPwdSafe
python -m venv .venv
source .venv/bin/activate     # Linux/macOS
.venv\Scripts\activate        # Windows
pip install -e .

imps "test-password"

For non-trivial changes please open an issue first to agree on the approach.

(back to top)


Contact

If you have a feature in mind that is not on the roadmap, or you disagree with something already on it, say so - the roadmap above is a plan, not a contract.

(back to top)


License

Released under the MIT License. See LICENSE for the full text.

Metadata

Release files for ismypwdsafe 1.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ismypwdsafe 1.1.0
File Size Uploaded Provenance
ismypwdsafe-1.1.0.tar.gz 23.5 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for ismypwdsafe 1.1.0
File Interpreter ABI Platform
ismypwdsafe-1.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 41.6 kB

Release files / ismypwdsafe-1.1.0.tar.gz

Download URL ismypwdsafe-1.1.0.tar.gz
Size 23.5 kB
Tags Source
SHA-256 checksum
How to use checksums
36a41db689c5510de3d6314d6140d401ace6a516f3bcd39ab3652540ebdcdce9
BLAKE2b-256 checksum
How to use checksums
94d1ec8026db929432c750367cdd3d063a02a414ff407fb179e1bf44842e6547
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

Release files / ismypwdsafe-1.1.0-py3-none-any.whl

Download URL ismypwdsafe-1.1.0-py3-none-any.whl
Size 18.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5f7db0e16b5a509f05980dea9c3f0d9c652eb27476d0c5d7624ccc5e6affcb0f
BLAKE2b-256 checksum
How to use checksums
ccfcab5bb8386d27f867847676b15235bceeb64404ad661f67a5587b08cf9858
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

Security for ismypwdsafe 1.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for ismypwdsafe-1.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page