Three prefix families and one checksum arithmetic tell you whether a Bitcoin address is real before you ever sign a transaction. A wallet paste error, a phishing copy, or a partial screenshot can all hand you a string that looks 26 to 90 characters of “random” base-58 characters — but if the version byte says mainnet while the HRP says testnet, or if the trailing four-quad-one bytes fail the double-SHA-256 check, the string is worthless as a destination. The validator at Elysia Tools runs the same four-step pipeline the reference clients use: prefix dispatch to Base58 or Bech32, alphabet-range checks, double-SHA-256 checksum verify for legacy, polymod checksum for SegWit, then a network cross-check against the selected network. Doing all four in one pass is the difference between a green check on a typo’d string and an irreversible transfer to a checksum-meddled phishing address.

What the validator does in one pass
The tool takes a single address string plus a network selector (Mainnet or Testnet) and emits one of three verdicts: Valid (with type, network, format, and 20-byte hash160), Invalid (with one or more human-readable errors), or Cross-network mismatch (valid checksum, wrong network — flagged before the type is trusted). The verdict comes from a four-stage decision tree: prefix → alphabet → checksum → network. Skip any stage and you risk false positives. A string starting with 1 that decodes Base58 cleanly is not yet a P2PKH mainnet address — the version byte still has to land on 0x00, and the four trailing checksum bytes still have to equal SHA256(SHA256(payload[:21]))[:4]. If you skip the version-byte check, a string starting with 1 whose decoded byte 0 is 0x05 would be falsely reported as P2PKH mainnet when it is in fact P2SH mainnet — both start with 1 vs 3 visually, but the prefix-family dispatch in the source code routes by decoded version, not by string prefix, for a reason. The dispatch details live in the same place: the validator page.
The three legacy address shapes and what each version byte means
Mainnet P2PKH addresses start with 1, decode to byte 0 = 0x00, and carry a 20-byte hash160 of the public key. They are the original “send-to-pubkey-hash” shape and remain the most common on consumer wallets for ledger zero-conf compatibility. Mainnet P2SH addresses start with 3, decode to byte 0 = 0x05, and are used for multisig and SegWit-wrapped scripts. Testnet equivalents use bytes 0x6f (P2PKH, prefix m/n) and 0xc4 (P2SH, prefix 2). The validator cross-checks the network selector against the decoded version byte and emits a network-mismatch error before trusting the type — so a testnet string pasted into the mainnet field is flagged immediately, not after a long decode pass.
Why Base58 — not Base64 — and what the alphabet gap means
Bitcoin’s legacy alphabet is the 58 characters that exclude 0, O, I, and l — characters that humans misread on printouts and wallet UIs. The validator scans every character against this alphabet before any decoding pass; if even one 0 slipped in (a common phishing trick, since real addresses never contain 0), it returns Invalid Base58 character: 0 and stops. This is also why a partial clipboard paste that drops a leading 1 produces an instant verdict — the truncated string is no longer 26 to 90 characters of valid Base58, and the validator’s length gate (26 to 90 characters inclusive) catches the drop before the alphabet pass even starts. Combining length + alphabet gives you a fast O(n) early-exit on bad input.

The double-SHA-256 checksum — why four bytes catch a typo
For Base58 addresses the payload is version_byte || hash160 (20 bytes) || checksum (4 bytes), totalling 25 bytes after Base58 decode. The four checksum bytes are the first four bytes of SHA256(SHA256(version_byte || hash160)). If even one byte of the 21-byte payload is flipped by a clipboard error, the recomputed checksum will not match — the chance of a random 32-bit collision is roughly one in 4.29 billion, so a typo’d address has effectively zero chance of passing. The validator surfaces this as a single line Invalid checksum and does not attempt to guess which byte was wrong — recovering the original is not possible from the wrong-string side. This is also why BIP-173 SegWit moved to Bech32: not because Base58 is broken, but because checksum recovery (error correction up to four characters) is a property you cannot bolt onto the double-SHA-256 construction.

Bech32 and Bech32m — polymod and the SegWit version distinction
Bech32 SegWit addresses (Taproot-rooted, BIP-173) start with bc1 on mainnet or tb1 on testnet. The human-readable part (HRP) is bc or tb, and the data part uses a 32-character alphabet (lowercase plus digits, excluding 1, b, i, o). The checksum is a polymod over the HRP-expanded data — six codewords, constant 1 — and the validator’s validateBech32Address path checks the HRP matches the network selector first, runs the polymod, and only then reports type Bech32. The newer Bech32m variant (BIP-350, used by Taproot since v1 segwit outputs) uses the same polymod but with constant 0x2bc830a3, which is what rejects any BIP-173 string from being treated as a Taproot output — same length and HRP, but the final checksum constant decides whether the witness version is v0 or v1+. The validator labels both as Bech32 and reports the witness version implicitly through the version-byte-less Bech32 output, which is enough for routing but not for full v0/v1 disambiguation in tooling that needs it.
The cross-network check that catches the silent loss
The most expensive validator bug is not a false negative — it is a false positive that routes the user to the wrong network. A mainnet address validated against Testnet produces isValid: false with the error Address is for mainnet but selected network is testnet, and the type stays reported as P2PKH / P2SH / Bech32 so the caller still knows what kind of address it is — just not the network they thought. Same path for testnet strings in the mainnet field. The validator returns isValid: false rather than silently accepting, and the hash160 is still populated on Base58 mismatches so downstream tooling can detect the wrong-network case without re-decoding. This is the exact pattern that prevents the “I sent real BTC to a testnet address” class of permanent loss.
When the validator is the right tool — and when it is not
Use the Bitcoin Address Validator when you need a fast, client-side sanity check on a paste or a screenshot — the kind of check that catches 0/O swaps, dropped leading characters, and the network-mismatch class of errors before you sign. Do not use it as a substitute for wallet-side verification of the destination before broadcast, and do not use it to validate private keys, WIFs, or extended public keys (xpub/ypub/zpub) — those are different formats with different version-byte trees and a different checksum construction. The tool validates addresses only. For BIP-39 mnemonic phrase checks, Bech32m-only disambiguation, or PSBT inspection, a different validator is the right tool. Treat the verdict as a yes/no gate before you commit a transaction, not as a guarantee of address ownership — only the recipient’s wallet can confirm they control the keys behind a hash160.
How to wire it into a payment workflow
The four-stage pipeline (prefix → alphabet → checksum → network) is small enough to mirror in your own code: regex the first character (1/3/m/n/2/bc1/tb1), scan against the alphabet, decode and verify the four-byte double-SHA-256 for Base58, run the polymod for Bech32, then compare the decoded network byte to your call site’s network. Doing it as four small stages is easier to test than a single fused validator, and the per-stage failure messages make downstream error handling trivial — a 0 slip gets a different message than a checksum failure, and your UI can show the right one. Run it before constructing the PSBT, not after — the cost is in the keystroke that hits “Send”, not in the validator call. Explore more validators and tools at elysiatools.com.
![Highlight card: how the four-byte checksum forms — SHA256(SHA256(version || hash160))[:4]](https://blog.flowrust.com/wp-content/uploads/2026/09/card3-48.png)