]> mj.ucw.cz Git - libucw.git/commitdiff
added base64 module, it is imported from somewhere :))
authorRobert Spalek <robert@ucw.cz>
Thu, 26 Sep 2002 13:08:48 +0000 (13:08 +0000)
committerRobert Spalek <robert@ucw.cz>
Thu, 26 Sep 2002 13:08:48 +0000 (13:08 +0000)
MJ, if you dislike the code too much, please let me know

lib/Makefile
lib/base64.c [new file with mode: 0644]
lib/base64.h [new file with mode: 0644]

index 32e8a2ae26ed0d64666db42477fa686c56afe2f7..4fbc7a196671a6325d2ea9fe313782e53204ba43 100644 (file)
@@ -8,7 +8,7 @@ SHLIB_OBJS=alloc.o alloc_str.o ctmatch.o db.o fastbuf.o fb-file.o fb-mem.o lists
        prime.o random.o realloc.o regex.o timer.o url.o wildmatch.o \
        wordsplit.o str_ctype.o str_upper.o bucket.o conf.o object.o sorter.o \
        finger.o proctitle.o ipaccess.o profile.o bitsig.o randomkey.o \
-       hashfunc.o base224.o fb-temp.o printf.o
+       hashfunc.o base64.o base224.o fb-temp.o printf.o
 
 obj/lib/libsh.a: $(addprefix obj/lib/,$(SHLIB_OBJS)) $(CUSTOM_MODULES)
 
diff --git a/lib/base64.c b/lib/base64.c
new file mode 100644 (file)
index 0000000..fe1a7c4
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ *     Base 64 Encoding & Decoding
+ *
+ *     (c) 2002, Robert Spalek <robert@ucw.cz>
+ *
+ */
+
+#undef LOCAL_DEBUG
+
+#include "lib/lib.h"
+#include "lib/base64.h"
+
+#include <string.h>
+
+static byte base64_table[] =
+       { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
+         'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+         'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
+         'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
+         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0'
+       };
+static byte base64_pad = '=';
+
+uns
+base64_encode(byte *dest, byte *src, uns len)
+{
+       byte *current = src;
+       uns i = 0;
+
+       while (len > 2) { /* keep going until we have less than 24 bits */
+               dest[i++] = base64_table[current[0] >> 2];
+               dest[i++] = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
+               dest[i++] = base64_table[((current[1] & 0x0f) << 2) + (current[2] >> 6)];
+               dest[i++] = base64_table[current[2] & 0x3f];
+
+               current += 3;
+               len -= 3; /* we just handle 3 octets of data */
+       }
+
+       /* now deal with the tail end of things */
+       if (len != 0) {
+               dest[i++] = base64_table[current[0] >> 2];
+               if (len > 1) {
+                       dest[i++] = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
+                       dest[i++] = base64_table[(current[1] & 0x0f) << 2];
+                       dest[i++] = base64_pad;
+               }
+               else {
+                       dest[i++] = base64_table[(current[0] & 0x03) << 4];
+                       dest[i++] = base64_pad;
+                       dest[i++] = base64_pad;
+               }
+       }
+       return i;
+}
+
+/* as above, but backwards. :) */
+uns
+base64_decode(byte *dest, byte *src, uns len)
+{
+       byte *current = src;
+       byte ch;
+       uns i = 0, j = 0;
+       static byte reverse_table[256];
+       static uns table_built = 0;
+
+       if (table_built == 0) {
+               byte *chp;
+               table_built = 1;
+               for(ch = 0; ch < 256; ch++) {
+                       chp = strchr(base64_table, ch);
+                       if(chp) {
+                               reverse_table[ch] = chp - base64_table;
+                       } else {
+                               reverse_table[ch] = 0xff;
+                       }
+               }
+       }
+
+       /* run through the whole string, converting as we go */
+       ch = 0;
+       while (len > 0) {
+               len--;
+               ch = *current++;
+               if (ch == base64_pad) break;
+
+               /* When Base64 gets POSTed, all pluses are interpreted as spaces.
+                  This line changes them back.  It's not exactly the Base64 spec,
+                  but it is completely compatible with it (the spec says that
+                  spaces are invalid).  This will also save many people considerable
+                  headache.  - Turadg Aleahmad <turadg@wise.berkeley.edu>
+                */
+
+               if (ch == ' ') ch = '+'; 
+
+               ch = reverse_table[ch];
+               if (ch == 0xff) continue;
+
+               switch(i % 4) {
+               case 0:
+                       dest[j] = ch << 2;
+                       break;
+               case 1:
+                       dest[j++] |= ch >> 4;
+                       dest[j] = (ch & 0x0f) << 4;
+                       break;
+               case 2:
+                       dest[j++] |= ch >>2;
+                       dest[j] = (ch & 0x03) << 6;
+                       break;
+               case 3:
+                       dest[j++] |= ch;
+                       break;
+               }
+               i++;
+       }
+       return j;
+}
diff --git a/lib/base64.h b/lib/base64.h
new file mode 100644 (file)
index 0000000..4ff2106
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ *     Base 64 Encoding & Decoding
+ *
+ *     (c) 2002, Robert Spalek <robert@ucw.cz>
+ *
+ *     This software may be freely distributed and used according to the terms
+ *     of the GNU Lesser General Public License.
+ */
+
+uns base64_encode(byte *dest, byte *src, uns len);
+uns base64_decode(byte *dest, byte *src, uns len);
+
+/*
+ * Use this macro to calculate buffer size.
+ */
+#define BASE64_ENC_LENGTH(x) (((x)+2)/3 *4)
+
+/*
+ * When called for BASE64_IN_CHUNK-byte chunks, the result will be
+ * always BASE64_OUT_CHUNK bytes long. If a longer block is split
+ * to such chunks, the result will be identical.
+ */
+#define BASE64_IN_CHUNK 3
+#define BASE64_OUT_CHUNK 4
+