Path: news.uiowa.edu!chi-news.cic.net!nntp.coast.net!news2.acs.oakland.edu!newshub.gmr.com!hobbes.tad.eds.com!maverick.tad.eds.com!news-admin@tad.eds.com From: Erick Wagner Newsgroups: comp.sys.apple2.comm Subject: Re: BASE64 Compression Date: 26 Feb 1996 19:13:41 GMT Organization: PRC Lines: 167 Message-ID: <4gt0p5$p2p@maverick.tad.eds.com> References: <4ft19a$15j@maverick.tad.eds.com> <4gqrg1$g2q@madeline.INS.CWRU.Edu> NNTP-Posting-Host: 148.94.8.235 Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Mailer: Mozilla 1.22 (Windows; I; 16bit) gj380@cleveland.Freenet.Edu (Adalbert Goertz) wrote: > >it would be nice if someone would write a base64 decompressor. I'm not sure who the original author was but here's some base64 source I snagged off the 'net (after using one of the search engines). I've used it a couple of times on the PC and it seems work okay, but I never come across base64-encoded data very often to say that this program works as it should... The only changes I've made to this source has been in the way of comments (especially usage notes). Good luck Erick /* BASE64.C PURPOSE Decode BASE64 encoded data NOTES This program expects to receive a BASE-64 encoded data stream via "stdin" and sends the decoded data stream to "stdout" pgm < inputfile > outputfile After using this program and depending on specific OS requirements, you may need to rename the file with the proper file extension, set the proper file type (and auxiliary file type if applicable), or perform additional manipulations before the new file will be recognized in the target environment. */ #include /* getchar(), putchar() */ #include /* exit() */ static unsigned char b64_bin[256]; /* => 0..63, pad=64, inv=65, else ign */ /* ------------- init_b64bin() ------------- setup B64 (ascii) => binary table */ static void init_b64bin(void) { int i,j; for(i = 0; i <= 32; i++) b64_bin[i] = 66; /* ignore controls */ for(i = 33; i < 127; i++) b64_bin[i] = 65; /* printable => inv */ for(i = 127; i <= 160; i++) b64_bin[i] = 66; /* ignore controls */ for(i = 161; i < 256; i++) b64_bin[i] = 65; /* printable => inv */ j = 0; for(i = 'A'; i <= 'Z'; i++, j++) b64_bin[i] = j; for(i = 'a'; i <= 'z'; i++, j++) b64_bin[i] = j; for(i = '0'; i <= '9'; i++, j++) b64_bin[i] = j; b64_bin['+'] = j++; b64_bin['/'] = j++; b64_bin['='] = 64; } /* ------------ GNC_b64bin() ------------ get next 6-bit group, or pad */ static int GNC_b64bin(unsigned int *ip) { int c; do { c = getchar(); if (c == EOF) return EOF; *ip = b64_bin[c & 0xFF]; } while(*ip > 65); return 0; } /* ----------- do_decode() ----------- decode => stdout */ static void do_decode(void) { int /*logical*/ done; unsigned int v6; unsigned int v24; /* room for >= 24 bits */ #define ERROR exit(2) done = 0; while(GNC_b64bin(&v6) != EOF) { if(done) ERROR; /* bytes following pad */ if(v6 > 63) ERROR; v24 = v6; if(GNC_b64bin(&v6) == EOF) ERROR; if(v6 > 63) ERROR; v24 = (v24 << 6) | v6; putchar((v24 >> (2*6-8)) & 0xFF); if(GNC_b64bin(&v6) == EOF) ERROR; if(v6 > 64) ERROR; /* invalid */ if(v6 == 64) { /* pad after 1 char */ done = 1; if(GNC_b64bin(&v6) == EOF) ERROR; if(v6 != 64) ERROR; } else { v24 = (v24 << 6) | v6; putchar((v24 >> (3*6-16)) & 0xFF); if(GNC_b64bin(&v6) == EOF) ERROR; if(v6 > 64) ERROR; /* invalid */ if(v6 == 64) { /* pad after 2 char */ done = 1; } else { putchar(((v24 << 6) | v6) & 0xFF); } } } exit(0); } int main(int argc, char **argv) { init_b64bin(); do_decode(); return 0; }