2 * UCW Library -- Base 64 Encoding & Decoding
4 * (c) 2002, Robert Spalek <robert@ucw.cz>
6 * This software may be freely distributed and used according to the terms
7 * of the GNU Lesser General Public License.
13 #include "ucw/base64.h"
17 static const byte base64_table[] =
18 { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
19 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
20 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
21 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
22 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0'
24 static const byte base64_pad = '=';
27 base64_encode(byte *dest, const byte *src, uns len)
29 const byte *current = src;
32 while (len > 2) { /* keep going until we have less than 24 bits */
33 dest[i++] = base64_table[current[0] >> 2];
34 dest[i++] = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
35 dest[i++] = base64_table[((current[1] & 0x0f) << 2) + (current[2] >> 6)];
36 dest[i++] = base64_table[current[2] & 0x3f];
39 len -= 3; /* we just handle 3 octets of data */
42 /* now deal with the tail end of things */
44 dest[i++] = base64_table[current[0] >> 2];
46 dest[i++] = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
47 dest[i++] = base64_table[(current[1] & 0x0f) << 2];
48 dest[i++] = base64_pad;
51 dest[i++] = base64_table[(current[0] & 0x03) << 4];
52 dest[i++] = base64_pad;
53 dest[i++] = base64_pad;
59 /* as above, but backwards. :) */
61 base64_decode(byte *dest, const byte *src, uns len)
63 const byte *current = src;
66 static byte reverse_table[256];
67 static uns table_built = 0;
69 if (table_built == 0) {
72 for(ch = 0; ch < 256; ch++) {
73 chp = strchr(base64_table, ch);
75 reverse_table[ch] = chp - base64_table;
77 reverse_table[ch] = 0xff;
82 /* run through the whole string, converting as we go */
87 if (ch == base64_pad) break;
89 /* When Base64 gets POSTed, all pluses are interpreted as spaces.
90 This line changes them back. It's not exactly the Base64 spec,
91 but it is completely compatible with it (the spec says that
92 spaces are invalid). This will also save many people considerable
93 headache. - Turadg Aleahmad <turadg@wise.berkeley.edu>
96 if (ch == ' ') ch = '+';
98 ch = reverse_table[ch];
99 if (ch == 0xff) continue;
106 dest[j++] |= ch >> 4;
107 dest[j] = (ch & 0x0f) << 4;
111 dest[j] = (ch & 0x03) << 6;