Skip to content
DonateБГ

Keys and addresses

Bech32

Bech32 addresses in Bitcoin: the bc1 format for SegWit and Taproot, with one letter case, a 32-character alphabet and a stronger checksum.

By Dimitar Zurnov · Updated 4 Nov 2026
Adapted from Learn Me a Bitcoin by Greg Walker.

Bech32 is the text format for SegWit and Taproot addresses, such as P2WPKH, P2WSH and P2TR. On mainnet, every Bech32 address starts with bc1. BIP 173 defined the format for SegWit version 0. BIP 350 defined Bech32m, the same design with a different checksum constant, for version 1 and later.

Why use Bech32 instead of Base58?

Bech32 keeps the job of a Base58 address but makes it easier to use.

  • One letter case. A Bech32 address never mixes upper and lower case, so it is easier to type and to read out loud. A wallet should reject a mixed-case address.
  • Fewer look-alike characters. The alphabet leaves out 1, b, i and o.
  • A stronger checksum. It guarantees detection of any error in up to 4 characters. A Base58Check checksum catches most errors but gives no such guarantee.
  • Smaller QR codes. QR codes have an alphanumeric mode for capital letters, digits and a few symbols. A Bech32 address written in capitals fits that mode, so the code needs less data.
  • Faster to process. Each character maps straight to a value. There is no big-number division, as in Base58.

What does a Bech32 address look like?

Type Example Length
P2WPKH bc1qrlsryzydvj8fyhc45f9qea4paq8sr0u3svqwyd 42 characters
P2WSH bc1q37qzzxnhnwdsde7yjzq5hc0wktmnqejp3zt0pj9l0pgn9f2gpyls4hahsc 62 characters
P2TR bc1p4pzgu93t5nlw9mscn0v6s7spfya7qntp0afynva267lr0vp0sxyqqj24dc 62 characters

The first example is the P2WPKH address of our example key. The other two are example addresses, and both are valid. The bc1 prefix shows mainnet. The character after it is the witness version: q means version 0, and p means version 1, which is Taproot. P2WPKH, P2WSH and P2TR are the three locking scripts that use these addresses.

What characters does Bech32 use?

The data part of an address uses 32 characters:

qpzry9x8gf2tvdw0s3jn54khce6mua7l

These are the digits 0 to 9 and the lower-case letters, without 1, b, i and o.

The number 1 is missing because it is the separator, and it looks like a lower-case l. The letter b is missing because it looks like 8 in capitals. The letter i can look like l, and o can look like 0. The first part of an address, the human-readable part, is not limited to this set. Bitcoin uses bc for mainnet, tb for testnet and bcrt for regtest.

How is a Bech32 address built?

A SegWit scriptPubKey is regrouped into 5-bit values, each value picks a base32 character, and the checksum is appended to give the address. scriptPubKey: 22 bytes 00 14 1fe032088d648e925f15a24a0cf6a1e80f01bf91 version 0, size 20, then the program drop the size, regroup bits 32 values of 5 bits each 3 31 16 3 4 2 4 13 12 18 7 9 4 23 24 21 20 9 5 0 25 29 21 1 29 0 7 16 3 15 28 17 Each value picks one base32 character. add the checksum Address (P2WPKH) bc1qrlsryzydvj8fyhc45f9qea4paq8sr0u3svqwyd prefix bc1, then the data and checksum
The example key's P2WPKH script, carried from the scriptPubKey to the address.

The steps below turn a SegWit scriptPubKey into an address. The example is the P2WPKH script of our key, which is 0014 followed by its public key hash.

  1. Choose the human-readable part. Use bc for mainnet, tb for testnet or bcrt for regtest.
  2. Take the scriptPubKey apart. It has three pieces: a version opcode, a size byte and the witness program. Drop the size byte. The decoder can work out the program length from the address itself.
  3. Convert the version to a 5-bit value. The version is the number behind the opcode, so OP_0 is 0 and OP_1 is 1. Do not use the raw byte as the version. The byte 51 is the opcode OP_1, which means version 1.
  4. Regroup the program into 5-bit values. Twenty bytes of 8 bits become 32 values of 5 bits. If the bits do not fill the last group, pad it with zeros.
  5. Calculate the checksum. It covers the human-readable part, the version and the program, as the next section explains. The result is six 5-bit values.
  6. Map each value to a character. Use the 32-character set above. The version comes first, then the program, then the checksum.
  7. Join the parts. Write the human-readable part, a 1, then the data.

For our key, the 32 program values are:

3 31 16 3 4 2 4 13 12 18 7 9 4 23 24 21 20 9 5 0 25 29 21 1 29 0 7 16 3 15 28 17

Those values spell rlsryzydvj8fyhc45f9qea4paq8sr0u3. The checksum is svqwyd. So the address is bc1 + q + the program characters + the checksum.

A Bech32 address has a prefix, a separator, a version character, a 32-character witness program and a six-character checksum. bc human-readable part: bc means mainnet 1 separator: always the last 1 q version 0, one character rlsryzydvj8fyhc45f9qea4paq8sr0u3 witness program: 20 bytes in 32 characters svqwyd checksum: six characters All five parts, joined: bc1qrlsryzydvj8fyhc45f9qea4paq8sr0u3svqwyd
Each part of the example P2WPKH address, from the prefix to the checksum.

How is the Bech32 checksum calculated?

The checksum is a BCH code, a type of error-detecting code. You do not need the algebra to use it. You need four things:

  • The human-readable part, expanded into 5-bit values. Take the top three bits of each character, add a zero, then take the low five bits of each character.
  • The version and the program, as 5-bit values.
  • Six zero values, which reserve room for the checksum.
  • A 30-bit register that starts at 1. For each 5-bit value, the register shifts left and takes in the value. The five bits that shifted out decide which of five fixed generator constants are XORed in.

When every value has been processed, XOR the register with a constant. For version 0 that constant is 1, as in Bech32. For version 1 and later it is 0x2bc830a3, as in Bech32m. The result is split into six 5-bit values. Those values are the checksum.

The script below builds a complete SegWit address with this method. It needs no library.

CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
BECH32_CONST = 1            # version 0 (BIP 173)
BECH32M_CONST = 0x2bc830a3  # version 1 and later (BIP 350)

def polymod(values):
    gen = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3]
    chk = 1
    for v in values:
        top = chk >> 25
        chk = ((chk & 0x1ffffff) << 5) ^ v
        for i in range(5):
            if (top >> i) & 1:
                chk ^= gen[i]
    return chk

def convert_bits(data, src, dst):
    """Regroup bits, e.g. 8-bit bytes into 5-bit groups (zero padded at the end)."""
    acc, bits, out = 0, 0, []
    for v in data:
        acc = (acc << src) | v
        bits += src
        while bits >= dst:
            bits -= dst
            out.append((acc >> bits) & ((1 << dst) - 1))
    if bits:
        out.append((acc << (dst - bits)) & ((1 << dst) - 1))
    return out

def segwit_address(hrp: str, version: int, program: bytes) -> str:
    const = BECH32_CONST if version == 0 else BECH32M_CONST
    data = [version] + convert_bits(program, 8, 5)
    values = [ord(c) >> 5 for c in hrp] + [0] + [ord(c) & 31 for c in hrp] + data
    pm = polymod(values + [0] * 6) ^ const
    checksum = [(pm >> 5 * (5 - i)) & 31 for i in range(6)]
    return hrp + "1" + "".join(CHARSET[d] for d in data + checksum)

print(segwit_address("bc", 0, bytes.fromhex("1fe032088d648e925f15a24a0cf6a1e80f01bf91")))
# bc1qrlsryzydvj8fyhc45f9qea4paq8sr0u3svqwyd
print(segwit_address("bc", 1, bytes.fromhex("a8448e162ba4fee2ee189bd9a87a01493be04d617f5249b3aad7be37b02f8188")))
# bc1p4pzgu93t5nlw9mscn0v6s7spfya7qntp0afynva267lr0vp0sxyqqj24dc

The second call uses a 32-byte Taproot program and produces a valid Bech32m address. Bitcoin Core's bech32.cpp uses the same algorithm.

How do you decode a Bech32 address?

Decoding reverses the steps, and it checks everything on the way.

  1. Find the separator. It is the last 1 in the string. Everything before it is the human-readable part, and everything after it is the data. Do not split at the first 1, and do not assume a fixed length for the prefix.
  2. Check the case. The whole address must be lower case or upper case, never mixed. Convert the address to lower case before you go on. A QR code often stores the capital form, so a scanner may return capitals.
  3. Map each data character to its value. The first value is the version, and the last six values are the checksum.
  4. Verify the checksum. Run the calculation above on the human-readable part and the data. The result must equal the constant for the version. If it does not, the address is invalid. The checksum guarantees detection of any error in up to 4 characters. A decoder may point to where an error might be, but it should not correct the address on its own, because a corrected string can be a different valid address (BIP 173).
  5. Convert the program back to bytes. Regroup the 5-bit values into 8-bit bytes. Any padding must be fewer than 5 bits and all zero.
  6. Check the program length. A version 0 program must be 20 or 32 bytes. Each address must be 90 characters or fewer in total, as BIP 173 sets.

When all the checks pass, rebuild the scriptPubKey from the version opcode, the length byte and the program.

What is Bech32m, and why was it needed?

Bech32m is the same design with a new constant. The reason is a weakness in the original Bech32 checksum. If the last character of an address is p, inserting or deleting any number of q characters just before it does not break the checksum. BIP 350 changes only the constant, which removes that weakness.

Witness version Constant Encoding Used for
0 1 Bech32 (BIP 173) P2WPKH and P2WSH
1 and later 0x2bc830a3 Bech32m (BIP 350) P2TR and future versions

Each constant gives its own checksum, so an address built with the wrong one fails validation. A Taproot address must use Bech32m. The Taproot example above checks out with the Bech32m constant and fails with the Bech32 one.

Where is Bech32 used?

  • P2WPKH (starts with bc1q) uses a 20-byte public key hash. SegWit went live with block 481,824, and this is the simplest SegWit output. See also SegWit.
  • P2WSH (starts with bc1q) uses a 32-byte script hash, for multisig and other scripts.
  • P2TR (starts with bc1p) uses a 32-byte tweaked public key. It went live with block 709,632. See also Taproot.

Base58 is still used for legacy P2PKH and P2SH addresses, for WIF keys and for extended keys.

What mistakes should you watch for?

  • Mixed case. A valid address never mixes upper and lower case, so a wallet should refuse it.
  • Look-alike characters. The letters 1, b, i and o are not in the set. A string with one of them is invalid.
  • Trusting the prefix. A string that starts with bc1 is not automatically valid. Check the checksum.
  • Missing or extra characters. A dropped or doubled character almost always breaks the checksum, so the address will not validate.
  • The wrong constant. A Taproot address must use Bech32m. A wallet that mixes the two will reject it.

Summary

Bech32 writes SegWit and Taproot addresses in one letter case, from a 32-character alphabet, with a checksum that is stronger than Base58Check's.

Version 0 uses the original constant from BIP 173, and version 1 and later use Bech32m from BIP 350. The address is the version, the witness program and the checksum, joined to the bc prefix with a 1. You can paste any bc1 address into our explorer, which reads it from our own node. The address page explains what the explorer shows for each one.

In this section: Keys and addresses

All of Bitcoin from zero

Something look wrong? Tell us