pbech32 0.1.0

Bech32 encoding and decoding library.
Documentation
  • Coverage
  • 100%
    32 out of 32 items documented22 out of 22 items with examples
  • Size
  • Source code size: 100.54 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 4.72 MB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 21s Average build duration of successful builds.
  • all releases: 21s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • Homepage
  • pablotron/pbech32
    0 0 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • pablotron

pbech32

Bech32 encoding and decoding library.

Links:

What is Bech32?

Bech32 is a fast and user-friendly base 32 encoding format that includes a namespace and checksum. Bech32m is an update to Bech32 with an improved checksum algorithm.

A Bech32 string contains a human-readable part (HRP), an encoded data part, and a 6 character checksum. The data part and checksum are base 32-encoded with a user-friendly alphabet that only contains lowercase ASCII alphanumeric characters.

Here is an example Bech32m string:

hello1vehkc6mn27xpct

Bech32 and Bech32m are specified in BIP173 and BIP350, respectively.

Library Features

Examples

Decode from string:

use pbech32::Bech32;

let s = "a1qypqxpq9mqr2hj"; // bech32m-encoded string
let got: Bech32 = s.parse()?; // decode string

assert_eq!(got.hrp.to_string(), "a"); // check human-readable part
assert_eq!(got.data, vec![1, 2, 3, 4, 5]); // check data

Encode to string:

use pbech32::{Bech32, Hrp, Scheme};

let scheme = Scheme::Bech32m; // checksum scheme
let hrp: Hrp = "a".parse()?; // human-readable part
let data = vec![1, 2, 3, 4, 5]; // data
let got = Bech32 { scheme, hrp, data }.to_string(); // encode as string

assert_eq!(got, "a1qypqxpq9mqr2hj"); // check result

Decoding a string verifies the checksum to catch mistakes:

use pbech32::{Bech32, Err};

let s = "a1wypqxpq9mqr2hj"; // string with error ("q" changed to "w")
let got = s.parse::<Bech32>(); // try to decode string

assert_eq!(got, Err(Err::InvalidChecksum)); // check result

Encode to a writer:

use std::io::Write;
use pbech32::{Encoder, Hrp, Scheme};

let mut vec: Vec<u8> = Vec::new(); // output vector
let hrp: Hrp = "hello".parse()?; // human readable part

let mut encoder = Encoder::new(&mut vec, Scheme::Bech32m, hrp)?; // create encoder
encoder.write_all(b"folks")?; // write data
encoder.flush()?; // flush encoder (REQUIRED)

let got = str::from_utf8(vec.as_ref())?; // convert output vector to string
assert_eq!(got, "hello1vehkc6mn27xpct"); // check result

Many error variants have a context field. Try to decode a string which has an invalid character at position 1:

use pbech32::{Bech32, Err};

let s = "a 1xxxxxx"; // string with invalid character at position 1
assert_eq!(s.parse::<Bech32>(), Err(Err::InvalidChar(1))); // check result

More examples are available in examples/.

Install

pbech32 package page on crates.io

Run cargo add pbech32 to add pbech32 as a dependency to an exiting Rust project:

$ cargo add pbech32

Run cargo install pbech32 to install the bech32 tool:

# install bech32 tool in cargo bin dir (e.g. `~/.cargo/bin`)
$ cargo install pbech32

Build

Run cargo build to create a debug build of the bech32 tool in target/debug/:

$ cargo build
...
$ echo -n hello | target/debug/bech32 encode; echo
example1dpjkcmr0qp8pe8

Run cargo build --release to create a release build of the bech32 tool in target/release/:

$ cargo build --release
...
$ echo -n 'hi there' | target/release/bech32 encode; echo
example1dp5jqargv4ex2at7pqx

You can also build the bech32 tool in a container using Podman or Docker like this:

$ podman run --rm -t -v "$PWD":/src -w /src docker.io/rust cargo build --release
...
$ echo -n foobarbaz | target/release/bech32 encode; echo
example1vehk7cnpwf3xz7sfaj6vp

To build a static binary of the example bech32 tool in a container:

$ podman run --rm -it -v "$PWD":/src -w /src rust sh -c "rustup target add $(arch)-unknown-linux-musl && cargo build --release --target $(arch)-unknown-linux-musl"
...
$ ldd target/x86_64-unknown-linux-musl/release/bech32
        statically linked
$ du -sh target/x86_64-unknown-linux-musl/release/bech32
580K    target/x86_64-unknown-linux-musl/release/bech32
$ echo -n hello | target/x86_64-unknown-linux-musl/release/bech32 encode; echo
example1dpjkcmr0qp8pe8

Documentation

pbech32 API documentation on docs.rs

Run cargo doc to build the API documentation locally in target/doc/pbech32/:

$ cargo doc
...
$ ls target/doc/pbech32/index.html
target/doc/pbech32/index.html

Run cargo doc --lib build the library documentation and exclude the bech32 tool documentation:

# remove generated docs
# (needed to clean up stale artifacts)
$ cargo clean --doc

# generate library-only docs
$ cargo doc --lib

Tests

Use cargo test to run the test suite:

$ cargo test
...
test result: ok. 46 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s

all doctests ran in 0.23s; merged doctests compilation took 0.22s

Use cargo clippy to run the linter:

$ cargo clippy
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.04s

Install cargo-tarpaulin and use cargo tarpaulin to check code coverage:

$ cargo tarpaulin
...
2026-03-08T07:38:10.235947Z  INFO cargo_tarpaulin::report: Coverage Results:
|| Uncovered Lines:
|| src/bin/bech32.rs: 113-116, 119, 124, 126, 161, 206-209
|| src/lib.rs: 799, 905-906, 923, 1494-1495, 1532, 1549
|| Tested/Total Lines:
|| src/bin/bech32.rs: 27/39
|| src/lib.rs: 190/198
||
91.56% coverage, 217/237 lines covered

Note: Some of the tests in src/bin/bech32.rs are ignored by default because the tests set environment variables which will cause tests in other threads to fail sporadically.

You can run the tests in a single thread and enable the ignored tests like this:

$ cargo tarpaulin -j1 -i
2026-03-08T07:38:49.813538Z  INFO cargo_tarpaulin::report: Coverage Results:
|| Uncovered Lines:
|| src/bin/bech32.rs: 119, 126, 161, 206-209
|| src/lib.rs: 799, 905-906, 923, 1494-1495, 1532, 1549
|| Tested/Total Lines:
|| src/bin/bech32.rs: 32/39 +12.82%
|| src/lib.rs: 190/198 +0.00%
||
93.67% coverage, 222/237 lines covered, +2.11% change in coverage