Decode a Bech32 or Bech32m string. */
| 372 | |
| 373 | /** Decode a Bech32 or Bech32m string. */ |
| 374 | DecodeResult Decode(const std::string& str, CharLimit limit) { |
| 375 | std::vector<int> errors; |
| 376 | if (!CheckCharacters(str, errors)) return {}; |
| 377 | size_t pos = str.rfind(SEPARATOR); |
| 378 | if (str.size() > limit) return {}; |
| 379 | if (pos == str.npos || pos == 0 || pos + CHECKSUM_SIZE >= str.size()) { |
| 380 | return {}; |
| 381 | } |
| 382 | data values(str.size() - 1 - pos); |
| 383 | for (size_t i = 0; i < str.size() - 1 - pos; ++i) { |
| 384 | unsigned char c = str[i + pos + 1]; |
| 385 | int8_t rev = CHARSET_REV[c]; |
| 386 | |
| 387 | if (rev == -1) { |
| 388 | return {}; |
| 389 | } |
| 390 | values[i] = rev; |
| 391 | } |
| 392 | std::string hrp; |
| 393 | hrp.reserve(pos); |
| 394 | for (size_t i = 0; i < pos; ++i) { |
| 395 | hrp += LowerCase(str[i]); |
| 396 | } |
| 397 | Encoding result = VerifyChecksum(hrp, values); |
| 398 | if (result == Encoding::INVALID) return {}; |
| 399 | return {result, std::move(hrp), data(values.begin(), values.end() - CHECKSUM_SIZE)}; |
| 400 | } |
| 401 | |
| 402 | /** Find index of an incorrect character in a Bech32 string. */ |
| 403 | std::pair<std::string, std::vector<int>> LocateErrors(const std::string& str, CharLimit limit) { |