// Based on code by Bob Trower (url: http://base64.sourceforge.net/b64.c)
// see the MIT license therein for further details

#include <stdlib.h>
#include <stdio.h>

// translation table for decoding
static const unsigned char cd64[] = "|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq";

//#define decode_block(a,b) ( *(unsigned int*)b = (((a[0]<<2|a[1]>>4)|((a[1]<<4|a[2]>>2)<<8))&0xFFFF|(((a[2]<<6&0xc0)|a[3])<<16)))

// decode 4 '6-bit' characters into 3 8-bit binary bytes
inline void decode_block(unsigned char in[4], unsigned char out[4]) {
    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]);
}

// populate the base64 mime buffer
char populate_block(unsigned char in[4]) {
    static int i;
    static char ch;
    for(i=0; i<4; i++) {
        while(((ch=getchar())!=EOF) && (ch==0x0D || ch==0x0A || ch=='$'));
		in[i] = (unsigned char) ((ch<43 || ch>122) ? 0 : cd64[ch-43])-62;
    }
    return ch;
}

// main: process input from stdin and output to stdout
int main(int argc, char *argv[]) {
    unsigned char in[4], out[4];
    int i;
    while(populate_block(in) != EOF) {
        decode_block(in, out);
        for(i=0; i<3; i++) putchar(out[i]);
    }
    return 0;
}

