Decode a Blech32 or Blech32m string. */
| 184 | |
| 185 | /** Decode a Blech32 or Blech32m string. */ |
| 186 | DecodeResult Decode(const std::string& str) { |
| 187 | bool lower = false, upper = false; |
| 188 | for (size_t i = 0; i < str.size(); ++i) { |
| 189 | unsigned char c = str[i]; |
| 190 | if (c >= 'a' && c <= 'z') lower = true; |
| 191 | else if (c >= 'A' && c <= 'Z') upper = true; |
| 192 | else if (c < 33 || c > 126) return {}; |
| 193 | } |
| 194 | if (lower && upper) return {}; |
| 195 | size_t pos = str.rfind('1'); |
| 196 | if (str.size() > 1000 || pos == str.npos || pos == 0 || pos + 13 > str.size()) { // ELEMENTS: 90->1000, 7->13 |
| 197 | return {}; |
| 198 | } |
| 199 | data values(str.size() - 1 - pos); |
| 200 | for (size_t i = 0; i < str.size() - 1 - pos; ++i) { |
| 201 | unsigned char c = str[i + pos + 1]; |
| 202 | int8_t rev = CHARSET_REV[c]; |
| 203 | |
| 204 | if (rev == -1) { |
| 205 | return {}; |
| 206 | } |
| 207 | values[i] = rev; |
| 208 | } |
| 209 | std::string hrp; |
| 210 | for (size_t i = 0; i < pos; ++i) { |
| 211 | hrp += LowerCase(str[i]); |
| 212 | } |
| 213 | Encoding result = VerifyChecksum(hrp, values); |
| 214 | if (result == Encoding::INVALID) return {}; |
| 215 | return {result, std::move(hrp), data(values.begin(), values.end() - 12)}; |
| 216 | } |
| 217 | |
| 218 | } // namespace blech32 |