| 92 | } |
| 93 | |
| 94 | bech32_encoding bech32_decode(char* hrp, uint8_t *data, size_t *data_len, const char *input, size_t max_input_len) { |
| 95 | uint32_t chk = 1; |
| 96 | size_t i; |
| 97 | size_t input_len = strlen(input); |
| 98 | size_t hrp_len; |
| 99 | int have_lower = 0, have_upper = 0; |
| 100 | if (input_len < 8 || input_len > max_input_len) { |
| 101 | return BECH32_ENCODING_NONE; |
| 102 | } |
| 103 | *data_len = 0; |
| 104 | while (*data_len < input_len && input[(input_len - 1) - *data_len] != '1') { |
| 105 | ++(*data_len); |
| 106 | } |
| 107 | hrp_len = input_len - (1 + *data_len); |
| 108 | if (1 + *data_len >= input_len || *data_len < 6) { |
| 109 | return BECH32_ENCODING_NONE; |
| 110 | } |
| 111 | *(data_len) -= 6; |
| 112 | for (i = 0; i < hrp_len; ++i) { |
| 113 | int ch = input[i]; |
| 114 | if (ch < 33 || ch > 126) { |
| 115 | return BECH32_ENCODING_NONE; |
| 116 | } |
| 117 | if (ch >= 'a' && ch <= 'z') { |
| 118 | have_lower = 1; |
| 119 | } else if (ch >= 'A' && ch <= 'Z') { |
| 120 | have_upper = 1; |
| 121 | ch = (ch - 'A') + 'a'; |
| 122 | } |
| 123 | hrp[i] = ch; |
| 124 | chk = bech32_polymod_step(chk) ^ (ch >> 5); |
| 125 | } |
| 126 | hrp[i] = 0; |
| 127 | chk = bech32_polymod_step(chk); |
| 128 | for (i = 0; i < hrp_len; ++i) { |
| 129 | chk = bech32_polymod_step(chk) ^ (input[i] & 0x1f); |
| 130 | } |
| 131 | ++i; |
| 132 | while (i < input_len) { |
| 133 | int v = (input[i] & 0x80) ? -1 : bech32_charset_rev[(int)input[i]]; |
| 134 | if (input[i] >= 'a' && input[i] <= 'z') have_lower = 1; |
| 135 | if (input[i] >= 'A' && input[i] <= 'Z') have_upper = 1; |
| 136 | if (v == -1) { |
| 137 | return BECH32_ENCODING_NONE; |
| 138 | } |
| 139 | chk = bech32_polymod_step(chk) ^ v; |
| 140 | if (i + 6 < input_len) { |
| 141 | data[i - (1 + hrp_len)] = v; |
| 142 | } |
| 143 | ++i; |
| 144 | } |
| 145 | if (have_lower && have_upper) { |
| 146 | return BECH32_ENCODING_NONE; |
| 147 | } |
| 148 | if (chk == bech32_final_constant(BECH32_ENCODING_BECH32)) { |
| 149 | return BECH32_ENCODING_BECH32; |
| 150 | } else if (chk == bech32_final_constant(BECH32_ENCODING_BECH32M)) { |
| 151 | return BECH32_ENCODING_BECH32M; |
no test coverage detected