Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) 2017 Pieter Wuille2// Copyright (c) 2021-present The Bitcoin Core developers3// Distributed under the MIT software license, see the accompanying4// file COPYING or http://www.opensource.org/licenses/mit-license.php.6#include <bech32.h>7#include <util/strencodings.h>9#include <boost/test/unit_test.hpp>11#include <string>13BOOST_AUTO_TEST_SUITE(bech32_tests)15BOOST_AUTO_TEST_CASE(bech32_testvectors_valid)16{17static const std::string CASES[] = {18"A12UEL5L",19"a12uel5l",20"an83characterlonghumanreadablepartthatcontainsthenumber1andtheexcludedcharactersbio1tt5tgs",21"abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw",22"11qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqc8247j",23"split1checkupstagehandshakeupstreamerranterredcaperred2y9e3w",24"?1ezyfcl",25};26for (const std::string& str : CASES) {27const auto dec = bech32::Decode(str);28BOOST_CHECK(dec.encoding == bech32::Encoding::BECH32);29std::string recode = bech32::Encode(bech32::Encoding::BECH32, dec.hrp, dec.data);30BOOST_CHECK(!recode.empty());31BOOST_CHECK(CaseInsensitiveEqual(str, recode));32}33}35BOOST_AUTO_TEST_CASE(bech32m_testvectors_valid)36{37static const std::string CASES[] = {38"A1LQFN3A",39"a1lqfn3a",40"an83characterlonghumanreadablepartthatcontainsthetheexcludedcharactersbioandnumber11sg7hg6",41"abcdef1l7aum6echk45nj3s0wdvt2fg8x9yrzpqzd3ryx",42"11llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllludsr8",43"split1checkupstagehandshakeupstreamerranterredcaperredlc445v",44"?1v759aa"45};46for (const std::string& str : CASES) {47const auto dec = bech32::Decode(str);48BOOST_CHECK(dec.encoding == bech32::Encoding::BECH32M);49std::string recode = bech32::Encode(bech32::Encoding::BECH32M, dec.hrp, dec.data);50BOOST_CHECK(!recode.empty());51BOOST_CHECK(CaseInsensitiveEqual(str, recode));52}53}55BOOST_AUTO_TEST_CASE(bech32_testvectors_invalid)56{57static const std::string CASES[] = {58" 1nwldj5",59"\x7f""1axkwrx",60"\x80""1eym55h",61"an84characterslonghumanreadablepartthatcontainsthenumber1andtheexcludedcharactersbio1569pvx",62"pzry9x0s0muk",63"1pzry9x0s0muk",64"x1b4n0q5v",65"li1dgmt3",66"de1lg7wt\xff",67"A1G7SGD8",68"10a06t8",69"1qzzfhee",70"a12UEL5L",71"A12uEL5L",72"abcdef1qpzrz9x8gf2tvdw0s3jn54khce6mua7lmqqqxw",73"test1zg69w7y6hn0aqy352euf40x77qddq3dc",74std::string(100, 'q'),75};76static const std::pair<std::string, std::vector<int>> ERRORS[] = {77{"Invalid character or mixed case", {0}},78{"Invalid character or mixed case", {0}},79{"Invalid character or mixed case", {0}},80{"Bech32 string too long", {90}},81{"Missing separator", {}},82{"Invalid separator position", {0}},83{"Invalid Base 32 character", {2}},84{"Invalid separator position", {2}},85{"Invalid character or mixed case", {8}},86{"Invalid checksum", {}}, // The checksum is calculated using the uppercase form so the entire string is invalid, not just a few characters87{"Invalid separator position", {0}},88{"Invalid separator position", {0}},89{"Invalid character or mixed case", {3, 4, 5, 7}},90{"Invalid character or mixed case", {3}},91{"Invalid Bech32 checksum", {11}},92{"Invalid Bech32 checksum", {9, 16}},93{"Bech32 string too long", {90}},94};95static_assert(std::size(CASES) == std::size(ERRORS), "Bech32 CASES and ERRORS should have the same length");97int i = 0;98for (const std::string& str : CASES) {99const auto& err = ERRORS[i];100const auto dec = bech32::Decode(str);101BOOST_CHECK(dec.encoding == bech32::Encoding::INVALID);102auto [error, error_locations] = bech32::LocateErrors(str);103BOOST_CHECK_EQUAL(err.first, error);104BOOST_CHECK(err.second == error_locations);105i++;106}107}109BOOST_AUTO_TEST_CASE(bech32m_testvectors_invalid)110{111static const std::string CASES[] = {112" 1xj0phk",113"\x7f""1g6xzxy",114"\x80""1vctc34",115"an84characterslonghumanreadablepartthatcontainsthetheexcludedcharactersbioandnumber11d6pts4",116"qyrz8wqd2c9m",117"1qyrz8wqd2c9m",118"y1b0jsk6g",119"lt1igcx5c0",120"in1muywd",121"mm1crxm3i",122"au1s5cgom",123"M1VUXWEZ",124"16plkw9",125"1p2gdwpf",126"abcdef1l7aum6echk45nj2s0wdvt2fg8x9yrzpqzd3ryx",127"test1zg69v7y60n00qy352euf40x77qcusag6",128};129static const std::pair<std::string, std::vector<int>> ERRORS[] = {130{"Invalid character or mixed case", {0}},131{"Invalid character or mixed case", {0}},132{"Invalid character or mixed case", {0}},133{"Bech32 string too long", {90}},134{"Missing separator", {}},135{"Invalid separator position", {0}},136{"Invalid Base 32 character", {2}},137{"Invalid Base 32 character", {3}},138{"Invalid separator position", {2}},139{"Invalid Base 32 character", {8}},140{"Invalid Base 32 character", {7}},141{"Invalid checksum", {}},142{"Invalid separator position", {0}},143{"Invalid separator position", {0}},144{"Invalid Bech32m checksum", {21}},145{"Invalid Bech32m checksum", {13, 32}},146};147static_assert(std::size(CASES) == std::size(ERRORS), "Bech32m CASES and ERRORS should have the same length");149int i = 0;150for (const std::string& str : CASES) {151const auto& err = ERRORS[i];152const auto dec = bech32::Decode(str);153BOOST_CHECK(dec.encoding == bech32::Encoding::INVALID);154auto [error, error_locations] = bech32::LocateErrors(str);155BOOST_CHECK_EQUAL(err.first, error);156BOOST_CHECK(err.second == error_locations);157i++;158}159}161BOOST_AUTO_TEST_SUITE_END()
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.