| 130 | } |
| 131 | |
| 132 | size_t base64Decode(char const* src, size_t len, char* output, size_t outLen) { |
| 133 | if (outLen == 0) |
| 134 | return 0; |
| 135 | |
| 136 | size_t written = 0; |
| 137 | |
| 138 | int i = 0, j = 0, in_ = 0, in_len = len; |
| 139 | unsigned char ca4[4], ca3[3]; |
| 140 | |
| 141 | while (in_len-- && (src[in_] != '=') && is_base64(src[in_])) { |
| 142 | ca4[i++] = src[in_++]; |
| 143 | if (i == 4) { |
| 144 | for (i = 0; i < 4; i++) |
| 145 | ca4[i] = base64_chars.find(ca4[i]); |
| 146 | ca3[0] = (ca4[0] << 2) + ((ca4[1] & 0x30) >> 4); |
| 147 | ca3[1] = ((ca4[1] & 0xf) << 4) + ((ca4[2] & 0x3c) >> 2); |
| 148 | ca3[2] = ((ca4[2] & 0x3) << 6) + ca4[3]; |
| 149 | for (i = 0; (i < 3); i++) { |
| 150 | --outLen; |
| 151 | *output = ca3[i]; |
| 152 | ++output; |
| 153 | ++written; |
| 154 | |
| 155 | if (outLen == 0) |
| 156 | return written; |
| 157 | } |
| 158 | i = 0; |
| 159 | } |
| 160 | } |
| 161 | |
| 162 | if (i) { |
| 163 | for (j = i; j < 4; j++) |
| 164 | ca4[j] = 0; |
| 165 | for (j = 0; j < 4; j++) |
| 166 | ca4[j] = base64_chars.find(ca4[j]); |
| 167 | ca3[0] = (ca4[0] << 2) + ((ca4[1] & 0x30) >> 4); |
| 168 | ca3[1] = ((ca4[1] & 0xf) << 4) + ((ca4[2] & 0x3c) >> 2); |
| 169 | ca3[2] = ((ca4[2] & 0x3) << 6) + ca4[3]; |
| 170 | for (j = 0; (j < i - 1); j++) { |
| 171 | --outLen; |
| 172 | *output = ca3[j]; |
| 173 | ++output; |
| 174 | ++written; |
| 175 | |
| 176 | if (outLen == 0) |
| 177 | return written; |
| 178 | } |
| 179 | } |
| 180 | |
| 181 | return written; |
| 182 | } |
| 183 | |
| 184 | String hexEncode(char const* data, size_t len) { |
| 185 | std::string res(len * 2, '\0'); |