16typedef std::vector<uint8_t> data;
 
   19const char* CHARSET = 
"qpzry9x8gf2tvdw0s3jn54khce6mua7l";
 
   22const int8_t CHARSET_REV[128] = {
 
   23    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
 
   24    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
 
   25    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
 
   26    15, -1, 10, 17, 21, 20, 26, 30,  7,  5, -1, -1, -1, -1, -1, -1,
 
   27    -1, 29, -1, 24, 13, 25,  9,  8, 23, -1, 18, 22, 31, 27, 19, -1,
 
   28     1,  0,  3, 16, 11, 28, 12, 14,  6,  4,  2, -1, -1, -1, -1, -1,
 
   29    -1, 29, -1, 24, 13, 25,  9,  8, 23, -1, 18, 22, 31, 27, 19, -1,
 
   30     1,  0,  3, 16, 11, 28, 12, 14,  6,  4,  2, -1, -1, -1, -1, -1
 
   34uint32_t EncodingConstant(
Encoding encoding) {
 
   42uint32_t PolyMod(
const data& v)
 
   90    for (
const auto v_i : v) {
 
  106        uint8_t c0 = c >> 25;
 
  109        c = ((c & 0x1ffffff) << 5) ^ v_i;
 
  120        if (c0 & 1)  c ^= 0x3b6a57b2; 
 
  121        if (c0 & 2)  c ^= 0x26508e6d; 
 
  122        if (c0 & 4)  c ^= 0x1ea119fa; 
 
  123        if (c0 & 8)  c ^= 0x3d4233dd; 
 
  124        if (c0 & 16) c ^= 0x2a1462b3; 
 
  131inline unsigned char LowerCase(
unsigned char c)
 
  133    return (c >= 
'A' && c <= 
'Z') ? (c - 
'A') + 
'a' : c;
 
  137data ExpandHRP(
const std::string& hrp)
 
  140    ret.reserve(hrp.size() + 90);
 
  141    ret.resize(hrp.size() * 2 + 1);
 
  142    for (
size_t i = 0; i < hrp.size(); ++i) {
 
  143        unsigned char c = hrp[i];
 
  145        ret[i + hrp.size() + 1] = c & 0x1f;
 
  152Encoding VerifyChecksum(
const std::string& hrp, 
const data& 
values)
 
  159    const uint32_t check = PolyMod(
Cat(ExpandHRP(hrp), 
values));
 
  166data CreateChecksum(
Encoding encoding, 
const std::string& hrp, 
const data& 
values)
 
  169    enc.resize(enc.size() + 6); 
 
  170    uint32_t mod = PolyMod(enc) ^ EncodingConstant(encoding); 
 
  172    for (
size_t i = 0; i < 6; ++i) {
 
  174        ret[i] = (mod >> (5 * (5 - i))) & 31;
 
  186    for (
const char& c : hrp) 
assert(c < 'A' || c > 
'Z');
 
  187    data checksum = CreateChecksum(encoding, hrp, 
values);
 
  189    std::string ret = hrp + 
'1';
 
  190    ret.reserve(ret.size() + combined.size());
 
  191    for (
const auto c : combined) {
 
  199    bool lower = 
false, upper = 
false;
 
  200    for (
size_t i = 0; i < str.size(); ++i) {
 
  201        unsigned char c = str[i];
 
  202        if (c >= 
'a' && c <= 
'z') lower = 
true;
 
  203        else if (c >= 
'A' && c <= 
'Z') upper = 
true;
 
  204        else if (c < 33 || c > 126) 
return {};
 
  206    if (lower && upper) 
return {};
 
  207    size_t pos = str.rfind(
'1');
 
  208    if (str.size() > 90 || pos == str.npos || pos == 0 || pos + 7 > str.size()) {
 
  211    data 
values(str.size() - 1 - pos);
 
  212    for (
size_t i = 0; i < str.size() - 1 - pos; ++i) {
 
  213        unsigned char c = str[i + pos + 1];
 
  214        int8_t rev = CHARSET_REV[c];
 
  222    for (
size_t i = 0; i < pos; ++i) {
 
  223        hrp += LowerCase(str[i]);
 
  227    return {result, std::move(hrp), data(
values.begin(), 
values.end() - 6)};
 
@ INVALID
Failed decoding.
@ BECH32
Bech32 encoding as defined in BIP173.
@ BECH32M
Bech32m encoding as defined in BIP350.
std::string Encode(Encoding encoding, const std::string &hrp, const data &values)
Encode a Bech32 or Bech32m string.
DecodeResult Decode(const std::string &str)
Decode a Bech32 or Bech32m string.
static const int64_t values[]
A selection of numbers that do not trigger int64_t overflow when added/subtracted.
V Cat(V v1, V &&v2)
Concatenate two vectors, moving elements.