Private Key Tools

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.

Any of these work: bc1qy86hkm0telzmvuvzm76279jp7z5p3yqjnaerk6 (P2WPKH, witness v0), bc1pmsrhxnvmj8tjxxu9wj69ntvwvhvr28qufyc26tshz3rjj777tx3sh54u63 (P2TR, witness v1), and their tb1โ€ฆ testnet forms. Upper case is accepted, mixed case is not.
No input yet

Enter a value above and press Convert. Not sure what to type? Press โ€œUse exampleโ€ to load the sample from the placeholder.

How it works

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:

scriptPubKey = OP_witnessversion โ€– <push> โ€– witness program
bc1qy86hkm0โ€ฆโ†’ hrp "bc"โ†’ separator 1โ†’ 5-bit data wordsโ†’ checksum constantโ†’ witness v0 + 20-byte programโ†’ 0014โ€ฆ

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

PartRuleIn bc1qy86hkm0telzmvuvzm76279jp7z5p3yqjnaerk6
Human-readable part (hrp)1โ€“83 US-ASCII characters, values 33โ€“126bc (mainnet) / tb (testnet)
SeparatorAlways the character 1; if the hrp contains 1, the last one separatesindex 2, one character
Data partAt least 6 characters from the 32-character charset; the final 6 are the checksumqy86hkm0telzmvuvzm76279jp7z5p3yqjnaerk6 (39 characters)
ChecksumThe last 6 data characters โ€” 30 bits, carrying no payload informationnaerk6
Total lengthAt most 90 characters42 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:

Value01234567
+0qpzry9x8
+8gf2tvdw0
+16s3jn54kh
+24ce6mua7l

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 sizeBits5-bit wordsZero padding bits
2 bytes (minimum)164 (20 bits)4
20 bytes (P2WPKH)16032 (160 bits)0
32 bytes (P2WSH / P2TR)25652 (260 bits)4
40 bytes (maximum)32064 (320 bits)0

Because the padding is at most four bits, the rule is strict, and a decoder must enforce it:

any incomplete final group MUST be at most 4 bits, MUST be all zero, and is discarded

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
PropertyValue
FieldGF(32) โ€” the 5-bit alphabet
Generator constants0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3
Checksum symbols6 characters = 30 bits
bech32 constant1
bech32m constant0x2bc830a3 = 734539939
Guaranteed detectionAny error affecting at most 4 characters
Chance of missing something worseLess 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 lengthDescription5 wrong chars6 wrong chars7+ wrong chars
8Longest detecting 6 errors01.1270.909 โ€“ 0.931
19Worst case for 6 errors0.0930.9720.931
39Length of a P2WPKH address0.7560.9350.931
59Length of a P2WSH address0.8050.9330.931
89Longest detecting 4 errors0.8670.9330.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:

The weakness, in BIP350's own words

"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:

Stringpolymod resultChecksum?
bc1qk4sgyl3plhx0pmh6w80r0m2m5pmknw75uteaqp1Valid bech32
bc1qk4sgyl3plhx0pmh6w80r0m2m5pmknw75uteaqqp (one q inserted)1Still passes the checksum
bc1qk4sgyl3plhx0pmh6w80r0m2m5pmknw75uteaqqqqp (three inserted)1Still passes the checksum
bc1qk4sgyl3plhx0pmh6w80r0m2m5pmknw75uteap (the existing q deleted)1Still 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.

bech32bech32m
Checksum constant10x2bc830a3
Governed byBIP173BIP350 (amends BIP173)
Used forWitness v0: P2WPKH, P2WSHWitness v1โ€“v16: P2TR and future types
q-insertion before a final pNot detected by the checksumDetected by the checksum
Conflict ruleNo 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

RuleRequirementSource
LengthAt most 90 characters overallBIP173
CaseAll lower or all upper; mixed case is invalidBIP173
hrpNon-empty; for Bitcoin addresses bc (mainnet) or tb (testnet)BIP173
SeparatorA 1 must exist; the last one is the separatorBIP173
Data partAt least 6 characters, all from the charsetBIP173
Checksum1 for v0, 0x2bc830a3 for v1+BIP173 / BIP350
Witness version0 โ€“ 16 inclusiveBIP173
Witness program2 โ€“ 40 bytesBIP141 / BIP173
v0 program sizeExactly 20 bytes (P2WPKH) or 32 bytes (P2WSH)BIP141
PaddingLeftover bits โ‰ค 4 and all zeroBIP173

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.

The witness-version range, and why it is easy to forget

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

StepValue
Addressbc1qy86hkm0telzmvuvzm76279jp7z5p3yqjnaerk6 (42 characters)
hrpbc
Separator index2
Data partqy86hkm0telzmvuvzm76279jp7z5p3yqjnaerk6 (39 characters)
First data valueq = 0 โ†’ witness version 0
Program words (checksum removed)y86hkm0telzmvuvzm76279jp7z5p3yqj (32 words)
5-bit values of those words4,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 charactersnaerk6
Checksum constant matched1 โ†’ bech32, BIP173
Witness program21f57b6debcfc5b67182dfb4af1641f0a8189012 (20 bytes)
scriptPubKey001421f57b6debcfc5b67182dfb4af1641f0a8189012
Readable scriptOP_0 <20-byte push> โ€” the classic P2WPKH output
Same program, testnettb1qy86hkm0telzmvuvzm76279jp7z5p3yqjemzsdf โ€” 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

StepValue
Addressbc1pmsrhxnvmj8tjxxu9wj69ntvwvhvr28qufyc26tshz3rjj777tx3sh54u63 (62 characters)
hrp / separator indexbc / 2
Data partpmsrhxnvmj8tjxxu9wj69ntvwvhvr28qufyc26tshz3rjj777tx3sh54u63 (59 characters)
First data valuep = 1 โ†’ witness version 1
Program wordsmsrhxnvmj8tjxxu9wj69ntvwvhvr28qufyc26tshz3rjj777tx3s (52 words)
Checksum charactersh54u63
Checksum constant matched0x2bc830a3 (734539939) โ†’ bech32m, BIP350
Witness programdc07734d9b91d7231b8574b459ad8e65d8351c1c4930ad2e171447297bde59a3 (32 bytes)
scriptPubKey5120dc07734d9b91d7231b8574b459ad8e65d8351c1c4930ad2e171447297bde59a3
Readable scriptOP_1 <32-byte push> โ€” OP_1 is opcode 0x51, not 0x01
Where the program comes fromIt 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:

TestResult
The address with its last character swapped for the next charset characterChecksum verification failed (the address contains a typo or is truncated)
The address with part of it upper-casedMixed 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 allNo separator "1" found
A character outside the charset, e.g. b in the data partCharacter "b" is not in the bech32 charset
More than 90 charactersLength 93 exceeds the BIP173 limit of 90 characters
A v0 program of 25 bytesWitness 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

Where this fits

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

ItemValue
Charsetqpzry9x8gf2tvdw0s3jn54khce6mua7l (32 characters, 5 bits each)
Separator1, the last occurrence
Checksum length6 characters (30 bits)
bech32 constant / BIP1 / BIP173 โ€” witness v0
bech32m constant / BIP0x2bc830a3 / BIP350 โ€” witness v1+
Max total length90 characters
v0 address lengths42 characters (P2WPKH) or 62 (P2WSH)
Program size2 โ€“ 40 bytes; v0 exactly 20 or 32
Guaranteed error detectionAny error affecting at most 4 characters
Known weaknessbech32 only: q-insertion/deletion before a final p