massively simplify base64 encoding.

This commit is contained in:
Joris Vink 2017-07-24 08:19:03 +02:00
parent 8215277483
commit fcc55453c7
2 changed files with 55 additions and 56 deletions

View File

@ -577,7 +577,7 @@ int kore_split_string(char *, const char *, char **, size_t);
void kore_strip_chars(char *, const char, char **); void kore_strip_chars(char *, const char, char **);
int kore_snprintf(char *, size_t, int *, const char *, ...); int kore_snprintf(char *, size_t, int *, const char *, ...);
long long kore_strtonum(const char *, int, long long, long long, int *); long long kore_strtonum(const char *, int, long long, long long, int *);
int kore_base64_encode(u_int8_t *, size_t, char **); int kore_base64_encode(const void *, size_t, char **);
int kore_base64_decode(char *, u_int8_t **, size_t *); int kore_base64_decode(char *, u_int8_t **, size_t *);
void *kore_mem_find(void *, size_t, void *, size_t); void *kore_mem_find(void *, size_t, void *, size_t);
char *kore_text_trim(char *, size_t); char *kore_text_trim(char *, size_t);

View File

@ -377,68 +377,67 @@ kore_time_ms(void)
} }
int int
kore_base64_encode(u_int8_t *data, size_t len, char **out) kore_base64_encode(const void *data, size_t len, char **out)
{ {
u_int32_t b; u_int8_t n;
struct kore_buf *res; size_t nb;
size_t plen, idx; const u_int8_t *ptr;
u_int8_t n, *pdata; u_int32_t bytes;
int i, padding; struct kore_buf result;
if ((len % 3) != 0) { ptr = data;
padding = 3 - (len % 3); kore_buf_init(&result, (len / 3) * 4);
plen = len + padding;
if (plen < len)
fatal("plen wrapped");
pdata = kore_malloc(plen); while (len > 0) {
memcpy(pdata, data, len); if (len > 2) {
memset(pdata + len, 0, padding); nb = 3;
} else { bytes = *ptr++ << 16;
plen = len; bytes |= *ptr++ << 8;
padding = 0; bytes |= *ptr++;
pdata = data; } else if (len > 1) {
} nb = 2;
bytes = *ptr++ << 16;
res = kore_buf_alloc(plen); bytes |= *ptr++ << 8;
} else if (len == 1) {
i = 2; nb = 1;
b = 0; bytes = *ptr++ << 16;
for (idx = 0; idx < plen; idx++) { } else {
b |= (pdata[idx] << (i * 8)); kore_buf_cleanup(&result);
if (i-- == 0) { return (KORE_RESULT_ERROR);
for (i = 3; i >= 0; i--) {
n = (b >> (6 * i)) & 0x3f;
if (n >= sizeof(b64table)) {
kore_debug("unable to encode %d", n);
kore_buf_free(res);
return (KORE_RESULT_ERROR);
}
if (idx >= len && i < padding)
break;
kore_buf_append(res, &(b64table[n]), 1);
}
b = 0;
i = 2;
} }
n = (bytes >> 18) & 0x3f;
kore_buf_append(&result, &(b64table[n]), 1);
n = (bytes >> 12) & 0x3f;
kore_buf_append(&result, &(b64table[n]), 1);
if (nb > 1) {
n = (bytes >> 6) & 0x3f;
kore_buf_append(&result, &(b64table[n]), 1);
if (nb > 2) {
n = bytes & 0x3f;
kore_buf_append(&result, &(b64table[n]), 1);
}
}
len -= nb;
} }
for (i = 0; i < padding; i++) switch (nb) {
kore_buf_append(res, (u_int8_t *)"=", 1); case 1:
kore_buf_appendf(&result, "==");
break;
case 2:
kore_buf_appendf(&result, "=");
break;
case 3:
break;
default:
kore_buf_cleanup(&result);
return (KORE_RESULT_ERROR);
}
if (pdata != data) /* result.data gets taken over so no need to cleanup result. */
kore_free(pdata); *out = kore_buf_stringify(&result, NULL);
pdata = kore_buf_release(res, &plen);
if ((plen + 1) < plen)
fatal("plen wrapped");
*out = kore_malloc(plen + 1);
(void)kore_strlcpy(*out, (char *)pdata, plen + 1);
kore_free(pdata);
return (KORE_RESULT_OK); return (KORE_RESULT_OK);
} }