/* SPDX-License-Identifier: GPL-3.0-or-later */ /* * base64.c * * Copyright (C) 2019 David Oberhollenzer */ #include "config.h" #include "internal.h" static sqfs_u8 convert(char in) { if (isupper(in)) return in - 'A'; if (islower(in)) return in - 'a' + 26; if (isdigit(in)) return in - '0' + 52; if (in == '+') return 62; if (in == '/' || in == '-') return 63; return 0; } size_t base64_decode(sqfs_u8 *out, const char *in, size_t len) { sqfs_u8 *start = out; while (len > 0) { unsigned int diff = 0, value = 0; while (diff < 4 && len > 0) { if (*in == '=' || *in == '_' || *in == '\0') { len = 0; } else { value = (value << 6) | convert(*(in++)); --len; ++diff; } } if (diff < 2) break; value <<= 6 * (4 - diff); switch (diff) { case 4: out[2] = value & 0xff; /* fall-through */ case 3: out[1] = (value >> 8) & 0xff; /* fall-through */ default: out[0] = (value >> 16) & 0xff; } out += (diff * 3) / 4; } *out = '\0'; return out - start; }