81size_t b64_encode(
char* dst,
const unsigned char* src,
size_t len);
92size_t b64_decode(
unsigned char* dst,
const char* src,
size_t len);
100#ifdef PICO_B64_IMPLEMENTATION
102#ifndef PICO_B64_ISALNUM
104#define PICO_B64_ISALNUM isalnum
107#ifndef PICO_B64_FLOOR
109#define PICO_B64_FLOOR floor
114#define PICO_B64_CEIL ceil
121static const char b64_table[] =
123 'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
124 'I',
'J',
'K',
'L',
'M',
'N',
'O',
'P',
125 'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
126 'Y',
'Z',
'a',
'b',
'c',
'd',
'e',
'f',
127 'g',
'h',
'i',
'j',
'k',
'l',
'm',
'n',
128 'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
129 'w',
'x',
'y',
'z',
'0',
'1',
'2',
'3',
130 '4',
'5',
'6',
'7',
'8',
'9',
'+',
'/'
139 return 4 * PICO_B64_CEIL(len / 3.0);
145 if (len > 0 && len % 4 != 0)
153 if (
'=' == src[len - 2])
155 else if (
'=' == src[len - 1])
158 return PICO_B64_FLOOR(3.0 * (len - padding) / 4.0);
164static inline void b64_encode_tmp(
unsigned char* buf,
unsigned char* tmp)
166 buf[0] = (tmp[0] & 0xfc) >> 2;
167 buf[1] = ((tmp[0] & 0x03) << 4) + ((tmp[1] & 0xf0) >> 4);
168 buf[2] = ((tmp[1] & 0x0f) << 2) + ((tmp[2] & 0xc0) >> 6);
169 buf[3] = tmp[2] & 0x3f;
172static inline void b64_decode_tmp(
unsigned char* buf,
unsigned char* tmp)
174 buf[0] = (tmp[0] << 2) + ((tmp[1] & 0x30) >> 4);
175 buf[1] = ((tmp[1] & 0xf) << 4) + ((tmp[2] & 0x3c) >> 2);
176 buf[2] = ((tmp[2] & 0x3) << 6) + tmp[3];
183size_t b64_encode(
char* dst,
const unsigned char* src,
size_t len)
188 unsigned char buf[4];
189 unsigned char tmp[3];
200 b64_encode_tmp(buf, tmp);
203 for (i = 0; i < 4; ++i)
205 dst[size++] = b64_table[buf[i]];
217 for (j = i; j < 3; ++j)
223 b64_encode_tmp(buf, tmp);
226 for (j = 0; j < i + 1; ++j)
228 dst[size++] = b64_table[buf[j]];
245static inline size_t b64_table_lookup(
char symbol)
249 for (i = 0; i < 64; ++i)
251 if (symbol == b64_table[i])
258size_t b64_decode(
unsigned char* dst,
const char * src,
size_t len)
263 unsigned char buf[3];
264 unsigned char tmp[4];
273 if (!PICO_B64_ISALNUM((
int)src[j]) &&
'+' != src[j] &&
'/' != src[j])
283 for (i = 0; i < 4; ++i)
285 tmp[i] = b64_table_lookup(tmp[i]);
289 b64_decode_tmp(buf, tmp);
292 for (i = 0; i < 3; ++i)
294 dst[size++] = buf[i];
306 for (j = i; j < 4; ++j)
312 for (j = 0; j < 4; ++j)
315 tmp[j] = b64_table_lookup(tmp[j]);
319 b64_decode_tmp(buf, tmp);
322 for (j = 0; j < i - 1; ++j)
324 dst[size++] = buf[j];
size_t b64_encode(char *dst, const unsigned char *src, size_t len)
Encodes an array of bytes into a Base64 encoded string (NOTE: A null terminator is not appended)
size_t b64_encoded_size(size_t len)
Returns the Base64 encoded size of an array of bytes (NOTE: This does not include a null terminator)
size_t b64_decode(unsigned char *dst, const char *src, size_t len)
Decodes a Base64 encoded string into an array of bytes (NOTE: A null terminator is not appended)
size_t b64_decoded_size(const char *src, size_t len)
Returns the decoded size of a Base64 string (NOTE: This does not include a null terminator)