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>
14 #include <ucw/threads.h>
18 static const byte base64_table[] =
19 { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
20 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
21 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
22 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
23 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0'
25 static const byte base64_pad = '=';
28 base64_encode(byte *dest, const byte *src, uint len)
30 const byte *current = src;
33 while (len > 2) { /* keep going until we have less than 24 bits */
34 dest[i++] = base64_table[current[0] >> 2];
35 dest[i++] = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
36 dest[i++] = base64_table[((current[1] & 0x0f) << 2) + (current[2] >> 6)];
37 dest[i++] = base64_table[current[2] & 0x3f];
40 len -= 3; /* we just handle 3 octets of data */
43 /* now deal with the tail end of things */
45 dest[i++] = base64_table[current[0] >> 2];
47 dest[i++] = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
48 dest[i++] = base64_table[(current[1] & 0x0f) << 2];
49 dest[i++] = base64_pad;
52 dest[i++] = base64_table[(current[0] & 0x03) << 4];
53 dest[i++] = base64_pad;
54 dest[i++] = base64_pad;
60 /* as above, but backwards. :) */
62 base64_decode(byte *dest, const byte *src, uint len)
64 const byte *current = src;
67 static byte reverse_table[256];
68 static uint table_built = 0;
70 if (table_built == 0) {
72 for(ch = 0; ch < 256; ch++) {
73 byte *chp = strchr(base64_table, ch);
75 reverse_table[ch] = chp - base64_table;
77 reverse_table[ch] = 0xff;
84 /* run through the whole string, converting as we go */
89 if (ch == base64_pad) break;
91 /* When Base64 gets POSTed, all pluses are interpreted as spaces.
92 This line changes them back. It's not exactly the Base64 spec,
93 but it is completely compatible with it (the spec says that
94 spaces are invalid). This will also save many people considerable
95 headache. - Turadg Aleahmad <turadg@wise.berkeley.edu>
98 if (ch == ' ') ch = '+';
100 ch = reverse_table[ch];
101 if (ch == 0xff) continue;
108 dest[j++] |= ch >> 4;
109 dest[j] = (ch & 0x0f) << 4;
113 dest[j] = (ch & 0x03) << 6;