Workshop o mikrokontrolérech na SKSP 2024.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

128 lines
4.1 KiB

3 months ago
/*
* UCW Library -- Base 64 Encoding & Decoding
*
* (c) 2002, Robert Spalek <robert@ucw.cz>
* (c) 2018, Pavel Charvat <pchar@ucw.cz>
*
* This software may be freely distributed and used according to the terms
* of the GNU Lesser General Public License.
*/
#undef LOCAL_DEBUG
#include <ucw/lib.h>
#include <ucw/base64.h>
const byte base64_enc_table[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const byte base64_dec_table[256] = {
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x3e, 0x80, 0x80, 0x80, 0x3f,
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x80, 0x80, 0x80, 0x40, 0x80, 0x80,
0x80, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
};
uint base64_encode(byte *dest, const byte *src, uint len)
{
const byte *ptr = src;
const byte *end = src + len;
byte *out = dest;
/* keep going until we have less than 24 bits */
if (end - ptr >= 3)
for (const byte *x = end - 2; ptr < x; )
{
out[0] = base64_enc_table[ptr[0] >> 2];
out[1] = base64_enc_table[((ptr[0] & 0x03) << 4) + (ptr[1] >> 4)];
out[2] = base64_enc_table[((ptr[1] & 0x0f) << 2) + (ptr[2] >> 6)];
out[3] = base64_enc_table[ptr[2] & 0x3f];
out += 4;
ptr += 3;
}
/* now deal with the tail end of things */
if (ptr != end)
{
out[0] = base64_enc_table[ptr[0] >> 2];
out[3] = BASE64_PADDING;
if (end - ptr >= 2)
{
out[1] = base64_enc_table[((ptr[0] & 0x03) << 4) + (ptr[1] >> 4)];
out[2] = base64_enc_table[(ptr[1] & 0x0f) << 2];
}
else
{
out[1] = base64_enc_table[(ptr[0] & 0x03) << 4];
out[2] = BASE64_PADDING;
}
out += 4;
}
return out - dest;
}
uint base64_decode(byte *dest, const byte *src, uint len)
{
const byte *ptr = src;
const byte *end = src + len;
byte *out = dest;
while (1)
{
uint val, ch;
do
{
if (ptr == end || (ch = base64_dec_table[*ptr++]) == BASE64_DEC_PADDING)
goto end;
}
while (ch > BASE64_DEC_PADDING);
val = ch;
do
{
if (ptr == end || (ch = base64_dec_table[*ptr++]) == BASE64_DEC_PADDING)
goto end; // Broken base64 encoding, we only have 6 bits
}
while (ch > BASE64_DEC_PADDING);
val = (val << 6) | ch;
do
{
if (ptr == end || (ch = base64_dec_table[*ptr++]) == BASE64_DEC_PADDING)
{
out[0] = val >> 4;
out += 1;
goto end;
}
}
while (ch > BASE64_DEC_PADDING);
val = (val << 6) | ch;
do
{
if (ptr == end || (ch = base64_dec_table[*ptr++]) == BASE64_DEC_PADDING)
{
out[0] = val >> 10;
out[1] = val >> 2;
out += 2;
goto end;
}
}
while (ch > BASE64_DEC_PADDING);
val = (val << 6) | ch;
out[0] = val >> 16;
out[1] = val >> 8;
out[2] = val;
out += 3;
}
end:
return out - dest;
}