aboutsummaryrefslogtreecommitdiffstats
path: root/util.c
diff options
context:
space:
mode:
authorWilmer van der Gaast <wilmer@gaast.net>2006-06-23 20:15:28 +0200
committerWilmer van der Gaast <wilmer@gaast.net>2006-06-23 20:15:28 +0200
commit812a41362a9316da1734fdaa8b1aad36bde9cb5c (patch)
treeac6aac55781de07e9e7e99ddfb2b8b74ab1debb2 /util.c
parent00ab35016e3646aa936ae0c3d7a8531ec68d6f24 (diff)
Added saner base64 encoding function (actually, moved the one from libyahoo2.c
to core, with some changes), which I need for the XML format password garbling.
Diffstat (limited to 'util.c')
-rw-r--r--util.c89
1 files changed, 38 insertions, 51 deletions
diff --git a/util.c b/util.c
index dfa0906b..d8d6a4c7 100644
--- a/util.c
+++ b/util.c
@@ -83,61 +83,48 @@ char *add_cr(char *text)
return ret;
}
-static char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" "0123456789+/";
-
-/* XXX Find bug */
char *tobase64(const char *text)
{
- char *out = NULL;
- const char *c;
- unsigned int tmp = 0;
- int len = 0, n = 0;
-
- c = text;
-
- while (*c) {
- tmp = tmp << 8;
- tmp += *c;
- n++;
-
- if (n == 3) {
- out = g_realloc(out, len + 4);
- out[len] = alphabet[(tmp >> 18) & 0x3f];
- out[len + 1] = alphabet[(tmp >> 12) & 0x3f];
- out[len + 2] = alphabet[(tmp >> 6) & 0x3f];
- out[len + 3] = alphabet[tmp & 0x3f];
- len += 4;
- tmp = 0;
- n = 0;
- }
- c++;
+ char *out;
+ int len;
+
+ len = strlen(text);
+ out = g_malloc((len + 2) /* the == padding */
+ / 3 /* every 3-byte block */
+ * 4 /* becomes a 4-byte one */
+ + 1); /* and of course, ASCIIZ! */
+
+ base64_encode_real(text, len, out, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=");
+
+ return out;
+}
+
+void base64_encode_real(const unsigned char *in, int inlen, unsigned char *out, char *b64digits)
+{
+ for (; inlen >= 3; inlen -= 3)
+ {
+ *out++ = b64digits[in[0] >> 2];
+ *out++ = b64digits[((in[0]<<4) & 0x30) | (in[1]>>4)];
+ *out++ = b64digits[((in[1]<<2) & 0x3c) | (in[2]>>6)];
+ *out++ = b64digits[in[2] & 0x3f];
+ in += 3;
}
- switch (n) {
-
- case 2:
- tmp <<= 8;
- out = g_realloc(out, len + 5);
- out[len] = alphabet[(tmp >> 18) & 0x3f];
- out[len + 1] = alphabet[(tmp >> 12) & 0x3f];
- out[len + 2] = alphabet[(tmp >> 6) & 0x3f];
- out[len + 3] = '=';
- out[len + 4] = 0;
- break;
- case 1:
- tmp <<= 16;
- out = g_realloc(out, len + 5);
- out[len] = alphabet[(tmp >> 18) & 0x3f];
- out[len + 1] = alphabet[(tmp >> 12) & 0x3f];
- out[len + 2] = '=';
- out[len + 3] = '=';
- out[len + 4] = 0;
- break;
- case 0:
- out = g_realloc(out, len + 1);
- out[len] = 0;
- break;
+ if (inlen > 0)
+ {
+ *out++ = b64digits[in[0] >> 2];
+ if (inlen > 1)
+ {
+ *out++ = b64digits[((in[0]<<4) & 0x30) | (in[1]>>4)];
+ *out++ = b64digits[((in[1]<<2) & 0x3c)];
+ }
+ else
+ {
+ *out++ = b64digits[((in[0]<<4) & 0x30) | (in[1]>>4)];
+ *out++ = b64digits[64];
+ }
+ *out++ = b64digits[64];
}
- return out;
+ *out = '\0';
}
char *normalize(const char *s)