Bech32 / Bech32m decoder & checksum verifier
Decode a bc1qโฆ or bc1pโฆ address into its human-readable part, witness version and witness program, see the five-bit words it is made of, prove which checksum constant matched โ and get a plain-language reason when the string is invalid.
Enter a value above and press Convert. Not sure what to type? Press โUse exampleโ to load the sample from the placeholder.
What this page does
A bech32 address is a base-32 string with a BCH checksum, and it decodes to exactly two facts: a
witness version and a witness program. Those two facts are the whole
address โ the scriptPubKey is literally OP_n followed by the program:
Paste any bc1โฆ, tb1โฆ, v0 or v1 address. This page shows every stage of the
decode, tells you which checksum constant matched (and therefore whether BIP173 or BIP350 applies), and
for invalid input prints the decoder's exact reason instead of guessing.
1. The shape of a bech32 string
| Part | Rule | In bc1qy86hkm0telzmvuvzm76279jp7z5p3yqjnaerk6 |
|---|---|---|
| Human-readable part (hrp) | 1โ83 US-ASCII characters, values 33โ126 | bc (mainnet) / tb (testnet) |
| Separator | Always the character 1; if the hrp contains 1, the last one separates | index 2, one character |
| Data part | At least 6 characters from the 32-character charset; the final 6 are the checksum | qy86hkm0telzmvuvzm76279jp7z5p3yqjnaerk6 (39 characters) |
| Checksum | The last 6 data characters โ 30 bits, carrying no payload information | naerk6 |
| Total length | At most 90 characters | 42 characters |
The separator exists so the hrp needs no escaping, and it is the digit 1 rather than a
symbol because punctuation survives copy-paste badly. 1 is safe because it is deliberately
not in the data charset, so the hrp boundary is never ambiguous.
2. The 5-bit charset, and why 5 bits
The data part is a base-32 string over this alphabet, in this order:
| Value | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|---|
| +0 | q | p | z | r | y | 9 | x | 8 |
| +8 | g | f | 2 | t | v | d | w | 0 |
| +16 | s | 3 | j | n | 5 | 4 | k | h |
| +24 | c | e | 6 | m | u | a | 7 | l |
Exactly 32 characters, so exactly 5 bits each โ that is the whole reason for the number. Note which
characters are missing: 1 (it is the separator), b, i and
o, so no two similar-looking glyphs both encode data. The alphabet also minimises the number
of visually similar pairs that differ in more than one bit, because the checksum is optimised for
detecting small numbers of bit errors.
The cost is length โ base32 needs about 15% more characters than base-256 โ and the benefit is no mixed case to get wrong, unambiguous reading out loud, and QR alphanumeric mode, which is 45% more compact than byte mode.
3. 8-to-5 conversion and the zero-padding rule
The witness program is a byte string; the data part is a string of 5-bit values. Conversion is most-significant-bit first: take the program's bits, chop them into groups of five, and pad the last group with zero bits if it is short.
| Program size | Bits | 5-bit words | Zero padding bits |
|---|---|---|---|
| 2 bytes (minimum) | 16 | 4 (20 bits) | 4 |
| 20 bytes (P2WPKH) | 160 | 32 (160 bits) | 0 |
| 32 bytes (P2WSH / P2TR) | 256 | 52 (260 bits) | 4 |
| 40 bytes (maximum) | 320 | 64 (320 bits) | 0 |
Because the padding is at most four bits, the rule is strict, and a decoder must enforce it:
A decoder that ignores this accepts several distinct strings for the same program, and it makes the
padding bits a place where a typo hides. Both BIPs ship test vectors for exactly this:
bc1zw508d6qejxtdg4y5r3zarvaryvqyzf3du uses "zero padding of more than 4 bits" and
tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3pjxtptv has "non-zero padding". This
page's decoder rejects both with Invalid padding: invalid padding โ it requires the leftover
bits after the last complete byte to be fewer than 5, and the shifted accumulator to be zero.
4. The BCH checksum
The checksum is not a hash. It is a BCH code over GF(32) โ a linear error-correcting code whose algebra gives guarantees about which errors are caught:
GEN = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3]
def polymod(values):
chk = 1
for v in values:
b = chk >> 25
chk = (chk & 0x1ffffff) << 5 ^ v
for i in range(5):
chk ^= GEN[i] if ((b >> i) & 1) else 0
return chk
# hrp is folded in as [high 3 bits of each char] + [0] + [low 5 bits of each char]
verify: polymod(hrp_expand(hrp) + data) == 1 # bech32
verify: polymod(hrp_expand(hrp) + data) == 0x2bc830a3 # bech32m
| Property | Value |
|---|---|
| Field | GF(32) โ the 5-bit alphabet |
| Generator constants | 0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3 |
| Checksum symbols | 6 characters = 30 bits |
| bech32 constant | 1 |
| bech32m constant | 0x2bc830a3 = 734539939 |
| Guaranteed detection | Any error affecting at most 4 characters |
| Chance of missing something worse | Less than 1 in 109 (asymptotically 1 in 230 = 0.931 per billion) |
The hrp is checksummed too, folded in high-bits-first: [ord(c) >> 5 for c in hrp] + [0] +
[ord(c) & 31 for c in hrp]. An error confined to the low five bits of an hrp character therefore
still lands inside the protected region. This is also why M1VUXWEZ is invalid โ its checksum
was computed over the uppercase hrp โ while
BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4 is valid.
BIP173 measured behaviour beyond four wrong characters. Counts are "per billion attempts"; a random 30-bit checksum fails 0.931 times per billion:
| Window length | Description | 5 wrong chars | 6 wrong chars | 7+ wrong chars |
|---|---|---|---|---|
| 8 | Longest detecting 6 errors | 0 | 1.127 | 0.909 โ 0.931 |
| 19 | Worst case for 6 errors | 0.093 | 0.972 | 0.931 |
| 39 | Length of a P2WPKH address | 0.756 | 0.935 | 0.931 |
| 59 | Length of a P2WSH address | 0.805 | 0.933 | 0.931 |
| 89 | Longest detecting 4 errors | 0.867 | 0.933 | 0.931 |
BIP350 repeats the exercise for bc1-shaped addresses. For a bech32m string checked by a
bech32m decoder: 24.34% of single-error patterns are detected with certainty and 75.66% with probability
1 โ 2โ30; for up to two errors inside a 28-character window, 16.85% / 83.15%; for up to two
errors anywhere, 15.72% / 84.23%, with 0.039% at 2โ25. The same strings checked by a
bech32 decoder do markedly worse โ the point of the clean break.
5. bech32 vs bech32m โ the insertion weakness that forced BIP350
This is the most important part of the page, because it explains why two nearly identical encodings exist for the same kind of address.
In 2020 it was discovered that bech32's checksum has a hole. Quoting BIP350:
"Bech32 has an unexpected weakness: whenever the final character is a 'p', inserting or deleting any number of 'q' characters immediately preceding it does not invalidate the checksum." Insertion and deletion were not part of the error classes the BCH code was optimised for, and there is no length information in the string, so a mutated string can remain a valid string โ with a different payload.
Reproduced here with this page's own decoder โ take a valid bech32 v0 address ending in p
and insert q characters before that final p:
| String | polymod result | Checksum? |
|---|---|---|
bc1qk4sgyl3plhx0pmh6w80r0m2m5pmknw75uteaqp | 1 | Valid bech32 |
bc1qk4sgyl3plhx0pmh6w80r0m2m5pmknw75uteaqqp (one q inserted) | 1 | Still passes the checksum |
bc1qk4sgyl3plhx0pmh6w80r0m2m5pmknw75uteaqqqqp (three inserted) | 1 | Still passes the checksum |
bc1qk4sgyl3plhx0pmh6w80r0m2m5pmknw75uteap (the existing q deleted) | 1 | Still passes the checksum |
BIP350's fix is minimal: keep everything and change only the constant XORed into the checksum, from
1 to 0x2bc830a3. The same insertion against a bech32m string no longer verifies
(polymod returns 920205498, not 734539939), so the mutation is caught by the
checksum rather than by luck.
| bech32 | bech32m | |
|---|---|---|
| Checksum constant | 1 | 0x2bc830a3 |
| Governed by | BIP173 | BIP350 (amends BIP173) |
| Used for | Witness v0: P2WPKH, P2WSH | Witness v1โv16: P2TR and future types |
q-insertion before a final p | Not detected by the checksum | Detected by the checksum |
| Conflict rule | No string can be valid as both: equal-length valid bech32 and bech32m strings differ in at least 3 characters | |
| Why not allow both for v0? | BIP350: that would reduce error detection to the equivalent of a 29-bit checksum | |
Two follow-on facts complete the picture. First, existing v0 addresses were never in danger: BIP350 notes
the weakness "does not affect existing uses of witness version 0 BIP173 addresses due to their restriction
to two specific lengths". Inserting a character changes the word count, so the program either changes size
or breaks the padding rule โ in our reproduction the mutated string is in fact rejected here by the
Invalid padding check, and a v1+ insertion is caught by the bech32m constant. Second, BIP173
itself added a 2024 disclosure: the scheme "is not always robust against the insertion and deletion of
fewer than 5 consecutive characters", which is why BIP173 now applies only to v0 outputs.
6. Validity rules this page enforces
| Rule | Requirement | Source |
|---|---|---|
| Length | At most 90 characters overall | BIP173 |
| Case | All lower or all upper; mixed case is invalid | BIP173 |
| hrp | Non-empty; for Bitcoin addresses bc (mainnet) or tb (testnet) | BIP173 |
| Separator | A 1 must exist; the last one is the separator | BIP173 |
| Data part | At least 6 characters, all from the charset | BIP173 |
| Checksum | 1 for v0, 0x2bc830a3 for v1+ | BIP173 / BIP350 |
| Witness version | 0 โ 16 inclusive | BIP173 |
| Witness program | 2 โ 40 bytes | BIP141 / BIP173 |
| v0 program size | Exactly 20 bytes (P2WPKH) or 32 bytes (P2WSH) | BIP141 |
| Padding | Leftover bits โค 4 and all zero | BIP173 |
Address lengths are therefore tightly constrained: 14โ74 characters, never a length โก 0, 3 or 5 (mod 8), and always 42 or 62 for v0.
Witness versions must be in the range 0โ16, because OP_n only exists for n โค 16; a string
whose version word is 17โ31 is not a valid segwit address even when its checksum, padding and
program length all check out. BIP350 lists exactly such a case as an invalid vector: the all-uppercase
string BC130XLXVLHEMJA6C4DQV22UAPCTQUPFHLXM9H8Z3K2E72Q4K9HCZ7VQ7ZWS8R (version 17) passes
every other rule. This decoder rejects it with
Witness version 17 is invalid: only versions 0-16 are defined โ try it in the box above to
see the rejection rendered, then compare it with bc1pโฆ, where the version word is 1.
7. Worked example: the demo P2WPKH address
| Step | Value |
|---|---|
| Address | bc1qy86hkm0telzmvuvzm76279jp7z5p3yqjnaerk6 (42 characters) |
| hrp | bc |
| Separator index | 2 |
| Data part | qy86hkm0telzmvuvzm76279jp7z5p3yqjnaerk6 (39 characters) |
| First data value | q = 0 โ witness version 0 |
| Program words (checksum removed) | y86hkm0telzmvuvzm76279jp7z5p3yqj (32 words) |
| 5-bit values of those words | 4,7,26,23,22,27,15,11,25,31,2,27,12,28,12,2,27,30,26,10,30,5,18,1,30,2,20,1,17,4,0,18 |
| Checksum characters | naerk6 |
| Checksum constant matched | 1 โ bech32, BIP173 |
| Witness program | 21f57b6debcfc5b67182dfb4af1641f0a8189012 (20 bytes) |
| scriptPubKey | 001421f57b6debcfc5b67182dfb4af1641f0a8189012 |
| Readable script | OP_0 <20-byte push> โ the classic P2WPKH output |
| Same program, testnet | tb1qy86hkm0telzmvuvzm76279jp7z5p3yqjemzsdf โ identical 20 bytes, different hrp, therefore a different checksum |
The witness program here equals the hash160 printed by hash160 โ addresses for the same key, and the testnet form carries the same program with a different 6-character checksum: the hrp is checksummed, so a mainnet/testnet mix-up cannot survive.
8. Worked example: the demo P2TR address
| Step | Value |
|---|---|
| Address | bc1pmsrhxnvmj8tjxxu9wj69ntvwvhvr28qufyc26tshz3rjj777tx3sh54u63 (62 characters) |
| hrp / separator index | bc / 2 |
| Data part | pmsrhxnvmj8tjxxu9wj69ntvwvhvr28qufyc26tshz3rjj777tx3sh54u63 (59 characters) |
| First data value | p = 1 โ witness version 1 |
| Program words | msrhxnvmj8tjxxu9wj69ntvwvhvr28qufyc26tshz3rjj777tx3s (52 words) |
| Checksum characters | h54u63 |
| Checksum constant matched | 0x2bc830a3 (734539939) โ bech32m, BIP350 |
| Witness program | dc07734d9b91d7231b8574b459ad8e65d8351c1c4930ad2e171447297bde59a3 (32 bytes) |
| scriptPubKey | 5120dc07734d9b91d7231b8574b459ad8e65d8351c1c4930ad2e171447297bde59a3 |
| Readable script | OP_1 <32-byte push> โ OP_1 is opcode 0x51, not 0x01 |
| Where the program comes from | It is the x coordinate of the tweaked output key: internal key ff812e26โฆee80, TapTweak bae91685โฆfa4d, output key dc07734dโฆ59a3 |
That last row is the difference between the two example addresses in one line: a P2WPKH program is the hash of a public key, while a P2TR program is a public key (the tweaked one). Everything else โ the encoding, the separator, the five-bit words, the six-character checksum โ is identical; only the version word and the checksum constant differ.
9. Failure paths, as this page shows them
The invalid strings below are tested live on every run, alongside whatever you paste:
| Test | Result |
|---|---|
| The address with its last character swapped for the next charset character | Checksum verification failed (the address contains a typo or is truncated) |
| The address with part of it upper-cased | Mixed case is not allowed in bech32 strings |
The v0 program re-encoded with the bech32m constant (BIP350 vector bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kemeawh) | Witness v0 must use bech32, not bech32m |
The v1 program re-encoded with the bech32 constant (BIP350 vector bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqh2y7hd) | Witness v1+ must use bech32m, not bech32 |
| No separator at all | No separator "1" found |
A character outside the charset, e.g. b in the data part | Character "b" is not in the bech32 charset |
| More than 90 characters | Length 93 exceeds the BIP173 limit of 90 characters |
| A v0 program of 25 bytes | Witness v0 program must be 20 bytes (P2WPKH) or 32 bytes (P2WSH) |
One scoping note, because it surprises people: BIP350's own test vectors include valid bech32m
strings such as A1LQFN3A that are not segwit addresses at all (their data part is
nothing but a checksum). A segwit decoder applies the address rules on top, so it rejects them โ
correctly, with a reason, and not with a crash.
10. Security notes and common mistakes
- Never let software "repair" an address. BIP173 is explicit: implementations should not correct beyond possibly indicating where an error might be, because a corrected address may not be the intended one and the funds go to the wrong place. Detection only.
- Lowercase is the wire format. Encoders must emit lowercase; uppercase is for display and QR codes (alphanumeric mode); a string must never mix the two.
bc1qโฆandbc1pโฆdiffer by one letter and one constant. The checksum constant is what makes it impossible to read one as the other.- A valid address is not necessarily spendable. A witness v2โv16 address, or a v0 program whose script you do not know, decodes perfectly and may be unspendable by any current software. Sending to one burns the coins.
Upstream: private key โ P2WPKH address, private key โ P2TR address and hash160 โ addresses build these strings. Downstream: Base58Check encoder / decoder covers version bytes, WIFs and checksum failures.
11. Quick reference
| Item | Value |
|---|---|
| Charset | qpzry9x8gf2tvdw0s3jn54khce6mua7l (32 characters, 5 bits each) |
| Separator | 1, the last occurrence |
| Checksum length | 6 characters (30 bits) |
| bech32 constant / BIP | 1 / BIP173 โ witness v0 |
| bech32m constant / BIP | 0x2bc830a3 / BIP350 โ witness v1+ |
| Max total length | 90 characters |
| v0 address lengths | 42 characters (P2WPKH) or 62 (P2WSH) |
| Program size | 2 โ 40 bytes; v0 exactly 20 or 32 |
| Guaranteed error detection | Any error affecting at most 4 characters |
| Known weakness | bech32 only: q-insertion/deletion before a final p |