Skip to content
Also from us: TypologyOnline.com · Free personality tests

Bech32 and Bech32m: Bitcoin SegWit and Taproot Address Encoding

How a checksummed base32-style format made Bitcoin addresses easier to read, safer to copy, and better suited to modern SegWit and Taproot address formats.

Try the Bech32 / Bech32m Encoder / Decoder tool
Illustration of Bech32 and Bech32m Bitcoin address encoding with prefix, data, and checksum sections
Bech32 and Bech32m turn structured data into human-readable strings with a prefix, separator, data words, and checksum.

Bech32 looks unusual the first time you meet it.

It does not look like hex. It does not look like Base64. It does not look like the older Bitcoin addresses that begin with 1 or 3.

Instead, a Bech32 Bitcoin address often looks something like this:

bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4

A Taproot-style Bech32m address looks more like this:

bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqzk5jj0

At first glance, these strings look cryptic. But Bech32 is not encryption. It is an encoding format: a way of turning structured data into readable text.

More specifically, Bech32 is a checksummed base32-style encoding designed for human-facing strings such as Bitcoin native SegWit addresses. Bech32m is a closely related variant introduced later for newer witness versions, including Taproot-style addresses.

The important idea is simple:

Bech32 turns structured data into a readable string with a built-in checksum, so software can detect many copying and typing mistakes.

This places Bech32 in the same broad family as Base58Check, Base64, Base32, hexadecimal, and other binary-to-text encodings.

But Bech32 has its own shape. It has a human-readable prefix. It has a separator. It uses a carefully chosen 32-character alphabet. It includes a checksum. It avoids mixed case. And in Bitcoin, it marks an important shift from older address formats toward native SegWit and Taproot-style address encodings.

That makes Bech32 and Bech32m useful not only as practical encoding systems, but also as teaching examples. They show how modern cryptographic software has to solve a problem that is not purely mathematical:

How do you make machine data safe enough for human hands?

Bech32 / Bech32m at a Glance

Feature Bech32 / Bech32m
Type Checksummed base32-style text encoding
Main use Bitcoin native SegWit and Taproot-style addresses
Encryption? No
Reversible? Yes, back to the encoded payload; not to a private key
Key required? No
Main structure Human-readable part + separator + data + checksum
Separator 1
Data alphabet qpzry9x8gf2tvdw0s3jn54khce6mua7l
Checksum length 6 characters
Bech32 checksum constant 0x01
Bech32m checksum constant 0x2bc830a3
Bitcoin Bech32 use Native SegWit witness version 0
Bitcoin Bech32m use Witness version 1 and later, including Taproot
Best use Learning address encodings, checksums, 5-bit data words, and human-readable prefixes

What Is Bech32?

Bech32 is a checksummed text encoding.

It was introduced for Bitcoin native SegWit addresses, but the underlying idea is more general. It provides a way to represent data using a restricted alphabet and a built-in checksum.

A Bech32 string has three main parts:

human-readable part + separator + data/checksum part

For example:

bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4

This can be read as:

Part Example Meaning
Human-readable part bc Identifies the context, such as Bitcoin mainnet
Separator 1 Separates the prefix from the encoded data
Data + checksum qw508d6... Encoded 5-bit values plus checksum characters

The human-readable part is often shortened to HRP.

In Bitcoin, common HRPs include:

HRP Meaning
bc Bitcoin mainnet
tb Bitcoin testnet
bcrt Bitcoin regtest

The separator is always:

1

Everything after the separator is encoded using the Bech32 character set.

So Bech32 is not merely "Base32 with a different alphabet." It is a complete address-style format with structure, context, and error detection.

Why Bech32 Was Created

Before Bech32, many Bitcoin addresses used Base58Check.

Base58Check was already a big improvement over raw bytes. It avoided confusing characters such as 0, O, I, and l, and it included a checksum. That made it useful for older Bitcoin address formats.

But Bech32 was designed for a newer generation of Bitcoin addresses.

Problem Bech32 improvement
Older address formats were not ideal for native SegWit Bech32 gives native SegWit outputs their own address format
Mixed case can be annoying and error-prone Bech32 avoids mixed case
Address errors need to be detected reliably Bech32 includes a strong checksum design
Wallets need to identify network/context Bech32 has a human-readable prefix
Addresses should be cleaner for copying and display Bech32 uses a restricted 32-character alphabet
Bitcoin needed room for future witness versions Bech32-style addresses encode the witness version

In other words, Bech32 was not created merely to look different.

It was designed to make a particular kind of Bitcoin address easier to handle, easier to validate, and harder to mistype unnoticed.

The Structure of a Bech32 String

A Bech32 string has this general form:

hrp + "1" + data + checksum

For example:

test1dpjkcmr09ys0qs

This example can be split as:

Component Value
HRP test
Separator 1
Data part dpjkcmr0
Checksum 9ys0qs

The checksum is always the final 6 characters.

So the string is not just one flat block of text. It contains pieces:

  • a human-readable prefix;
  • a separator;
  • encoded data;
  • a checksum.

This structure is one of the main differences between Bech32 and simpler encodings such as Base64.

Base64 usually just says:

Here are some bytes, represented as text.

Bech32 says something closer to:

Here is a named, contextual string, with encoded data and an error-detecting checksum.

That makes it very suitable for addresses.

The Bech32 Alphabet

Bech32 uses this 32-character alphabet:

qpzry9x8gf2tvdw0s3jn54khce6mua7l

This alphabet is not the same as ordinary Base32.

Ordinary Base32 often uses something like:

ABCDEFGHIJKLMNOPQRSTUVWXYZ234567

Bech32 uses a custom ordering of characters. The data part is usually written in lowercase, and mixed case is invalid.

That last point matters.

A Bech32 string can be all lowercase or all uppercase, but it should not mix the two. In practice, Bitcoin addresses are normally written in lowercase.

This kind of casing is acceptable:

bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4

This kind of mixed casing is not:

bc1Qw508D6qejxtdg4y5r3zarvary0c5xw7kv8f3t4

The reason is practical. Mixed-case strings are harder to read, harder to type, and less friendly for systems that may transform text.

Bech32 keeps things cleaner.

How Bech32 Works

Bech32 works by representing data as a sequence of 5-bit values.

That is why it is base32-style.

A normal byte has 8 bits. A Bech32 data value has 5 bits. Since 5 bits can represent 2^5 = 32 different values, each value can be mapped to one character in the Bech32 alphabet.

The basic flow is:

  1. Start with bytes.
  2. Convert the bytes into 5-bit values.
  3. Map each 5-bit value to a character in the Bech32 alphabet.
  4. Compute a checksum from the HRP and data values.
  5. Append the checksum characters.
  6. Place the HRP and separator at the front.

Visually:

bytes -> 5-bit words -> Bech32 characters -> checksum -> final string

This is different from Base58.

Base58 treats the whole byte sequence as one very large integer and repeatedly divides by 58. Bech32 instead works with 5-bit data values and a checksum algorithm.

So although both Base58Check and Bech32 are used for human-facing Bitcoin strings, they do not work in exactly the same way.

A Tiny Worked Example

Take the text:

hello

In UTF-8, this becomes the hex bytes:

68 65 6C 6C 6F

Those bytes are ordinary 8-bit values.

To encode them as Bech32, they are converted into 5-bit groups.

Using the HRP:

test

and the Bech32 variant, the result is:

test1dpjkcmr09ys0qs

This can be split as:

Part Value
HRP test
Separator 1
Encoded data dpjkcmr0
Checksum 9ys0qs
Full Bech32 test1dpjkcmr09ys0qs

The same payload using Bech32m gives a different checksum:

test1dpjkcmr0scqr9j

Notice that the beginning is the same:

test1dpjkcmr0

But the checksum ending is different:

Variant Output
Bech32 test1dpjkcmr09ys0qs
Bech32m test1dpjkcmr0scqr9j

That is because Bech32 and Bech32m use the same general structure but different checksum constants.

The payload has not become secret. It has been encoded. Anyone with the right decoder can recover the original bytes.

Important: Bech32 Text Is Not Automatically a Bitcoin Address

A generic Bech32 encoder can encode ordinary text, bytes, or other payloads.

That does not automatically make the result a Bitcoin address.

A valid Bitcoin SegWit address has extra Bitcoin-specific rules. It needs:

  • the correct network prefix, such as bc for mainnet or tb for testnet;
  • a valid witness version;
  • a valid witness program;
  • the correct checksum variant;
  • the correct payload length for the type of address.

So this is a valid Bech32 string for the text hello:

test1dpjkcmr09ys0qs

But it is not a Bitcoin wallet address.

It is just an educational Bech32 example.

This distinction matters because Bech32 is a general encoding format, while a Bitcoin address is a specific use of that format.

A Bech32 encoder teaches the representation layer. A Bitcoin wallet has to do much more.

What Is Bech32m?

Bech32m is a modified version of Bech32.

It keeps the same general structure:

hrp + "1" + data + checksum

It uses the same character set:

qpzry9x8gf2tvdw0s3jn54khce6mua7l

It still has a 6-character checksum.

The key difference is the checksum constant.

Variant Checksum constant Bitcoin use
Bech32 0x01 Witness version 0
Bech32m 0x2bc830a3 Witness version 1 and later

Bech32m was introduced after a weakness was identified in the original Bech32 checksum design for certain future witness versions. Rather than replacing Bech32 entirely, Bitcoin kept Bech32 for witness version 0 outputs and adopted Bech32m for witness version 1 and later witness outputs.

That is why the distinction matters:

SegWit v0 -> Bech32
SegWit v1 and later -> Bech32m

Taproot uses witness version 1, so Taproot-style addresses use Bech32m.

Bech32, Bech32m, SegWit, and Taproot

In Bitcoin address terms, Bech32 and Bech32m are most often discussed with SegWit and Taproot.

The common shape is:

bc1...

The bc part means Bitcoin mainnet. The 1 is the Bech32 separator.

After that, the first data character can indicate the witness version.

For many native SegWit version 0 addresses, the address begins:

bc1q...

The q character represents data value 0 in the Bech32 alphabet, corresponding to witness version 0.

For many Taproot-style addresses, the address begins:

bc1p...

The p character represents data value 1, corresponding to witness version 1.

So, in broad terms:

Address start Common meaning Variant
bc1q... Bitcoin mainnet native SegWit v0 Bech32
tb1q... Bitcoin testnet native SegWit v0 Bech32
bc1p... Bitcoin mainnet Taproot-style v1 Bech32m
tb1p... Bitcoin testnet Taproot-style v1 Bech32m

This is not the whole story of Bitcoin address validation, but it is a useful first mental model.

Bech32 and Bech32m are address encodings. They are not private keys, signatures, transactions, wallets, or encryption.

They are the readable outer form for certain structured data.

Why the Human-Readable Part Matters

The human-readable part is not decoration.

It tells software and humans what kind of string they are looking at.

For Bitcoin:

HRP Meaning
bc Bitcoin mainnet
tb Bitcoin testnet
bcrt Bitcoin regtest

The HRP also participates in the checksum. That means if the prefix changes, the checksum should no longer validate.

This is useful. It means a string meant for one context is less likely to be accidentally accepted as valid in another context.

For example, changing a bc1... address into a tb1... address by editing the prefix should break the checksum. The prefix is part of the protected structure.

That is one of Bech32's strengths. It does not just encode data. It binds the readable prefix into the checksum calculation.

The Checksum

Bech32 and Bech32m both include a 6-character checksum.

The checksum is calculated from:

  • the human-readable part;
  • the separator structure;
  • the data values;
  • the variant constant.

In simplified terms, the checksum asks:

Does this whole string still fit the Bech32 or Bech32m rules?

If one character is mistyped, removed, added, or changed, the checksum will usually fail.

That does not make the address secure in a cryptographic secrecy sense. It makes it safer to handle.

A checksum is not a lock. It is an error detector.

That matters for addresses because people copy them from screens, scan them from QR codes, paste them into wallets, and compare them in stressful situations.

Bech32 was designed with that human edge in mind.

Bech32 Is Not Encryption

Bech32 is not encryption.

Bech32m is not encryption either.

They do not use a secret key. They do not hide information. They do not protect private keys. They do not make a wallet safe. They do not prove that an address is trustworthy.

They encode data and include a checksum.

That is useful, but it is not secrecy.

This distinction is especially important because Bech32 often appears near Bitcoin, wallets, addresses, Taproot, and other cryptographic terms. The surrounding ecosystem is cryptographic. The encoding itself is not encryption.

Weaknesses and Limitations

Bech32 and Bech32m are useful, but they are not magic.

Their main limitations are:

Limitation Why it matters
Not encryption Anyone can decode the payload structure
Not a private-key format by itself An address is not a secret key
Context matters A valid Bech32 string is not automatically a valid Bitcoin address
Variant rules matter Using Bech32 where Bech32m is required can be invalid
HRP matters Prefixes such as bc, tb, and bcrt have specific meanings
Checksums detect errors, not intent A valid checksum does not prove the destination is safe
Software validation is still needed Wallets must check witness version, program length, and network rules

So the right way to think about Bech32 is:

It is a careful representation format, not a complete security system.

That is still important.

Good representation prevents mistakes. But it does not replace wallet security, address verification, or user caution.

How Bech32 Is "Broken"

You do not usually "break" Bech32 the way you break a cipher, because Bech32 is not trying to hide a secret.

If you know the format, you can decode it.

The useful security question is different:

Can the string be validated, and does the decoded structure make sense for the intended use?

For example, a Bitcoin wallet should check:

  • Is the HRP correct for this network?
  • Is the checksum valid?
  • Is the string Bech32 or Bech32m as required?
  • Is the witness version valid?
  • Is the witness program length valid?
  • Is the address type supported?

An attacker does not need to "decrypt" a Bech32 address. They may instead try to trick a user into copying the wrong valid address, or use lookalike context, malware, clipboard replacement, phishing, or wallet confusion.

That is why the checksum is helpful but not sufficient.

It catches many accidental errors. It does not tell you whether you meant to send funds to that destination.

Bech32 sits alongside several other text encodings:

Encoding Relationship
Hex Represents bytes using base-16 digits
Base32 Also uses 5-bit values, but with a different alphabet and no Bech32 checksum structure
Base58 Human-friendly binary-to-text encoding popularised by Bitcoin
Base58Check Base58 plus version/checksum, used for older Bitcoin-style address formats
Bech32 Checksummed base32-style encoding used for native SegWit v0
Bech32m Modified Bech32 checksum used for witness version 1 and later

Base58Check and Bech32 are especially worth comparing.

Feature Base58Check Bech32 / Bech32m
Main Bitcoin association Legacy/classic address-style encoding Native SegWit and Taproot-style addresses
Separator None 1
Human-readable prefix Usually version byte, not visible as text Visible HRP such as bc or tb
Alphabet size 58 32
Case style Mixed uppercase/lowercase alphabet Usually lowercase, no mixed case
Checksum First 4 bytes of double SHA-256 6-character polymod checksum
Encryption? No No

Base58Check belongs to the older visible surface of Bitcoin.

Bech32 and Bech32m belong to the newer visible surface.

A Simple Python Bech32 and Bech32m Implementation

Here is a simple educational implementation of Bech32 and Bech32m.

It is written for clarity rather than speed. The goal is to show the structure: HRP expansion, 5-bit data values, checksum creation, and Bech32/Bech32m encoding.

Python exampleShow code
CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"

BECH32_CONST = 0x01
BECH32M_CONST = 0x2BC830A3


def bech32_polymod(values):
    """Internal checksum function used by Bech32 and Bech32m."""
    generators = [
        0x3B6A57B2,
        0x26508E6D,
        0x1EA119FA,
        0x3D4233DD,
        0x2A1462B3,
    ]

    chk = 1

    for value in values:
        top = chk >> 25
        chk = ((chk & 0x1FFFFFF) << 5) ^ value

        for i in range(5):
            if (top >> i) & 1:
                chk ^= generators[i]

    return chk


def hrp_expand(hrp):
    """Expand the human-readable part for checksum calculation."""
    return [ord(char) >> 5 for char in hrp] + [0] + [ord(char) & 31 for char in hrp]


def create_checksum(hrp, data, variant="bech32"):
    """Create the 6 checksum values for Bech32 or Bech32m."""
    if variant == "bech32":
        constant = BECH32_CONST
    elif variant == "bech32m":
        constant = BECH32M_CONST
    else:
        raise ValueError("Variant must be 'bech32' or 'bech32m'.")

    values = hrp_expand(hrp) + data
    polymod = bech32_polymod(values + [0, 0, 0, 0, 0, 0]) ^ constant

    return [(polymod >> 5 * (5 - i)) & 31 for i in range(6)]


def verify_checksum(hrp, data):
    """Return 'bech32', 'bech32m', or None depending on checksum validity."""
    check = bech32_polymod(hrp_expand(hrp) + data)

    if check == BECH32_CONST:
        return "bech32"

    if check == BECH32M_CONST:
        return "bech32m"

    return None


def bech32_encode(hrp, data, variant="bech32"):
    """Encode 5-bit data values as Bech32 or Bech32m."""
    if not hrp:
        raise ValueError("HRP cannot be empty.")

    hrp = hrp.lower()
    checksum = create_checksum(hrp, data, variant)
    combined = data + checksum

    return hrp + "1" + "".join(CHARSET[value] for value in combined)


def bech32_decode(text):
    """Decode a Bech32 or Bech32m string.

    Returns:
        (hrp, data_without_checksum, variant)
    """
    if text.lower() != text and text.upper() != text:
        raise ValueError("Bech32 strings cannot mix uppercase and lowercase.")

    text = text.lower()

    if "1" not in text:
        raise ValueError("Missing Bech32 separator '1'.")

    separator_index = text.rfind("1")
    hrp = text[:separator_index]
    data_text = text[separator_index + 1:]

    if not hrp:
        raise ValueError("Missing human-readable part.")

    if len(data_text) < 6:
        raise ValueError("Data part is too short to contain a checksum.")

    data = []

    for char in data_text:
        if char not in CHARSET:
            raise ValueError(f"Invalid Bech32 character: {char!r}")

        data.append(CHARSET.index(char))

    variant = verify_checksum(hrp, data)

    if variant is None:
        raise ValueError("Invalid Bech32 / Bech32m checksum.")

    return hrp, data[:-6], variant


def convert_bits(data, from_bits, to_bits, pad=True):
    """Convert a sequence of integers from one bit-group size to another."""
    accumulator = 0
    bits = 0
    result = []
    max_value = (1 << to_bits) - 1
    max_accumulator = (1 << (from_bits + to_bits - 1)) - 1

    for value in data:
        if value < 0 or value >> from_bits:
            raise ValueError("Invalid value for bit conversion.")

        accumulator = ((accumulator << from_bits) | value) & max_accumulator
        bits += from_bits

        while bits >= to_bits:
            bits -= to_bits
            result.append((accumulator >> bits) & max_value)

    if pad:
        if bits:
            result.append((accumulator << (to_bits - bits)) & max_value)
    else:
        if bits >= from_bits:
            raise ValueError("Invalid padding.")
        if (accumulator << (to_bits - bits)) & max_value:
            raise ValueError("Non-zero padding.")

    return result


message = "hello"
payload_bytes = message.encode("utf-8")

# Convert ordinary 8-bit bytes into 5-bit Bech32 data values.
data_words = convert_bits(payload_bytes, 8, 5, pad=True)

encoded_bech32 = bech32_encode("test", data_words, variant="bech32")
encoded_bech32m = bech32_encode("test", data_words, variant="bech32m")

print("Plaintext :", message)
print("Hex bytes :", payload_bytes.hex(" ").upper())
print("Bech32    :", encoded_bech32)
print("Bech32m   :", encoded_bech32m)

hrp, decoded_words, variant = bech32_decode(encoded_bech32)
decoded_bytes = bytes(convert_bits(decoded_words, 5, 8, pad=False))

print("Decoded HRP     :", hrp)
print("Decoded variant :", variant)
print("Decoded text    :", decoded_bytes.decode("utf-8"))

Expected output:

Plaintext : hello
Hex bytes : 68 65 6C 6C 6F
Bech32    : test1dpjkcmr09ys0qs
Bech32m   : test1dpjkcmr0scqr9j
Decoded HRP     : test
Decoded variant : bech32
Decoded text    : hello

The most important thing in the code is not one single line. It is the movement:

bytes -> 5-bit words -> Bech32 text

and then back again:

Bech32 text -> 5-bit words -> bytes

The checksum validates whether the string is probably intact. It does not make the data secret.

Reading the Code Like the Encoding

The Bech32 alphabet is stored here:

CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"

Each character corresponds to a 5-bit value from 0 to 31.

The human-readable part is expanded here:

def hrp_expand(hrp):
    return [ord(char) >> 5 for char in hrp] + [0] + [ord(char) & 31 for char in hrp]

This means the HRP is not just pasted onto the front visually. It participates in the checksum calculation.

The checksum is created here:

polymod = bech32_polymod(values + [0, 0, 0, 0, 0, 0]) ^ constant

The constant is the key difference between Bech32 and Bech32m:

BECH32_CONST = 0x01
BECH32M_CONST = 0x2BC830A3

The conversion from ordinary bytes to 5-bit data words happens here:

data_words = convert_bits(payload_bytes, 8, 5, pad=True)

That is the step that turns normal byte data into Bech32-compatible values.

Decoding reverses the process:

decoded_bytes = bytes(convert_bits(decoded_words, 5, 8, pad=False))

That is Bech32 in programming form.

Common Questions About Bech32

Is Bech32 encryption?

No. Bech32 is encoding with a checksum. It does not hide data and does not use a secret key.

Is Bech32m encryption?

No. Bech32m is also not encryption. It is a modified Bech32 checksum variant used for newer witness versions such as Taproot-style Bitcoin addresses.

What is the difference between Bech32 and Bech32m?

They use the same general structure and alphabet, but different checksum constants. Bech32 uses 0x01. Bech32m uses 0x2bc830a3.

Why was Bech32m introduced?

Bech32m was introduced to fix a weakness in the original Bech32 checksum design for newer witness versions. Bitcoin keeps Bech32 for witness version 0 and uses Bech32m for witness version 1 and later.

Why do Bitcoin Bech32 addresses start with bc1?

The bc part is the human-readable prefix for Bitcoin mainnet, and 1 is the Bech32 separator.

What does bc1q mean?

In many Bitcoin addresses, bc1q indicates a Bitcoin mainnet native SegWit version 0 address. The q represents data value 0, which corresponds to witness version 0.

What does bc1p mean?

In many Bitcoin addresses, bc1p indicates a Bitcoin mainnet Taproot-style address. The p represents data value 1, which corresponds to witness version 1. These use Bech32m.

Can Bech32 encode ordinary text?

Yes. Ordinary text can be converted into bytes, then regrouped into 5-bit values and encoded as Bech32. For example, hello with HRP test becomes:

test1dpjkcmr09ys0qs

Is a valid Bech32 string always a valid Bitcoin address?

No. A string can be valid Bech32 without being a valid Bitcoin address. Bitcoin addresses require additional wallet and network rules.

Can I generate a Bitcoin address just by encoding text as Bech32?

No. A simple Bech32 encoder can show how the encoding works, but wallet address generation is a separate process involving keys, scripts, witness versions, witness programs, wallet rules, and security checks.

Should I paste real wallet data into a Bech32 tool?

No. Do not paste real wallet seeds, private keys, recovery phrases, or sensitive financial data into ordinary online tools.

Why Bech32 Still Matters

Bech32 matters because it shows that cryptographic systems need careful human-facing representation.

It is not enough for data to be mathematically valid. It must also be readable, copyable, typable, scannable, and checkable.

Bech32 solves that problem with:

  • a readable HRP;
  • a clear separator;
  • a restricted alphabet;
  • no mixed case;
  • 5-bit data words;
  • a checksum that includes the prefix;
  • a visible address style for native SegWit.

Bech32m continues the same idea for newer Bitcoin address types, especially witness version 1 and later.

That makes Bech32 and Bech32m excellent teaching examples. They sit between pure encoding, checksum design, wallet usability, and the human reality of copying important strings correctly.

They are not encryption.

They are not private keys.

They are not magic.

But they do something important:

They make structured data safer for human hands.

That is why Bech32 still matters.

Not because it hides data.

Because it helps people carry important data without breaking it.

Sources and further reading

Try the Bech32 / Bech32m Encoder / Decoder Tool

Want to experiment with the idea in practice? Open the matching tool and try your own text.

Open Bech32 / Bech32m Encoder / Decoder
Signal acquired

A note from the team

We build these tools because we love cryptography, encoding, and making difficult ideas easier to explore. If they've helped you, even a small coffee means the world to the project. Thank you!

Say thanks on Ko-fi

Read next

Binary-to-Text Encoding Base58 and Base58Check: The Encoding Bitcoin Made Famous How a compact alphabet without 0, O, I, or l helped turn raw bytes into human-friendly strings for Bitcoin addresses, checksummed data, and copy-safe identifiers. Binary-to-Text Encoding Base32: The Encoding That Makes Binary Easier to Read, Copy, and Survive How a 5-bit alphabet became a quiet helper in authenticator apps, DNS-safe strings, recovery codes, identifiers, and text-shaped software systems. Byte Encoding Hex Encoder / Decoder: Seeing Text as Bytes How hexadecimal turns raw bytes into readable base-16 pairs, and why 41 means A, but not secrecy.
Back to all articles