summaryrefslogtreecommitdiffstats
path: root/nanohttp/nanohttp-base64.c
diff options
context:
space:
mode:
Diffstat (limited to 'nanohttp/nanohttp-base64.c')
-rw-r--r--nanohttp/nanohttp-base64.c143
1 files changed, 143 insertions, 0 deletions
diff --git a/nanohttp/nanohttp-base64.c b/nanohttp/nanohttp-base64.c
new file mode 100644
index 0000000..f81039c
--- /dev/null
+++ b/nanohttp/nanohttp-base64.c
@@ -0,0 +1,143 @@
+/******************************************************************
+* $Id: nanohttp-base64.c,v 1.1 2006/02/19 22:22:41 snowdrop Exp $
+*
+* CSOAP Project: A http client/server library in C
+* Copyright (C) 2003 Ferhat Ayaz
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Library General Public
+* License as published by the Free Software Foundation; either
+* version 2 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Library General Public License for more details.
+*
+* You should have received a copy of the GNU Library General Public
+* License along with this library; if not, write to the
+* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+* Boston, MA 02111-1307, USA.
+*
+* Email: hero@persua.de
+******************************************************************/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+static const char cb64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+static const char cd64[] = "|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq";
+
+/**
+ * encode 3 8-bit binary bytes as 4 '6-bit' characters
+ */
+static void encodeblock(unsigned char in[3], unsigned char out[4], int len)
+{
+ out[0] = cb64[in[0] >> 2];
+ out[1] = cb64[((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4)];
+ out[2] = (unsigned char)(len > 1 ? cb64[((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6)] : '=');
+ out[3] = (unsigned char)(len > 2 ? cb64[in[2] & 0x3f] : '=');
+
+ return;
+}
+
+/**
+ * base64 encode a string.
+ */
+void base64_encode(const unsigned char *instr, unsigned char *outstr)
+{
+ unsigned char in[3], out[4];
+ int i, len;
+
+ while (*instr) {
+
+ len = 0;
+ for (i = 0; i < 3; i++) {
+ in[i] = (unsigned char)*instr++;
+ if (*instr) {
+ len++;
+ }
+ else {
+ in[i] = 0;
+ }
+ }
+ if (len) {
+ encodeblock(in, out, len);
+ for (i = 0; i < 4; i++) {
+ *outstr++ = out[i];
+ }
+ }
+ }
+}
+
+/**
+ * decode 4 '6-bit' characters into 3 8-bit binary bytes
+ */
+static void decodeblock(unsigned char in[4], unsigned char out[3])
+{
+ out[0] = (unsigned char)(in[0] << 2 | in[1] >> 4);
+ out[1] = (unsigned char)(in[1] << 4 | in[2] >> 2);
+ out[2] = (unsigned char)(((in[2] << 6) & 0xc0) | in[3]);
+
+ return;
+}
+
+/**
+ * decode a base64 encoded string (maybe broken...)
+ */
+void base64_decode(const unsigned char *instr, unsigned char *outstr)
+{
+ unsigned char in[4], out[3], v;
+ int i, len;
+
+ while (*instr) {
+ for (len = 0, i = 0; i < 4 && *instr; i++) {
+ v = 0;
+ while (*instr && v == 0) {
+ v = *instr++;
+ v = (unsigned char)((v < 43 || v > 122) ? 0 : cd64[v - 43]);
+ if (v) {
+ v = (unsigned char)((v == '$') ? 0 : v - 61);
+ }
+ }
+ if (*instr) {
+ len++;
+ if (v) {
+ in[i] = (unsigned char)(v - 1);
+ }
+ }
+ else {
+ in[i] = 0;
+ }
+ }
+ if (len) {
+ decodeblock(in, out);
+ for (i = 0; i < len - 1; i++) {
+ *outstr++ = out[i];
+ }
+ }
+ }
+}
+
+#ifdef BASE64_TEST_CASE_FROM_RFC2617
+int main(int argc, char **argv) {
+
+
+ unsigned char *instr = "QWxhZGRpbjpvcGVuIHNlc2FtZQ==";
+ unsigned char instr2[80];
+ unsigned char outstr[80];
+
+ bzero(outstr, 80);
+
+ base64_decode(instr, outstr);
+
+ printf("\"%s\" => \"%s\"\n", instr, outstr);
+
+ strcpy(instr2, outstr);
+
+ base64_encode(instr2, outstr);
+
+ return printf("\"%s\" => \"%s\"\n", instr2, outstr);
+}
+#endif