#include #include #include static char *radixN = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; static char pad = '='; radix_encode(inbuf, outbuf, len, decode) unsigned char inbuf[], outbuf[]; int *len, decode; { int i,j,D; char *p; unsigned char c; if (decode) { for (i=0,j=0; inbuf[i] && inbuf[i] != pad; i++) { if ((p = strchr(radixN, inbuf[i])) == NULL) return(1); D = p - radixN; switch (i&3) { case 0: outbuf[j] = D<<2; break; case 1: outbuf[j++] |= D>>4; outbuf[j] = (D&15)<<4; break; case 2: outbuf[j++] |= D>>2; outbuf[j] = (D&3)<<6; break; case 3: outbuf[j++] |= D; } } switch (i&3) { case 1: return(3); case 2: if (D&15) return(3); if (strcmp((char *)&inbuf[i], "==")) return(2); break; case 3: if (D&3) return(3); if (strcmp((char *)&inbuf[i], "=")) return(2); } *len = j; } else { for (i=0,j=0; i < *len; i++) switch (i%3) { case 0: outbuf[j++] = radixN[inbuf[i]>>2]; c = (inbuf[i]&3)<<4; break; case 1: outbuf[j++] = radixN[c|inbuf[i]>>4]; c = (inbuf[i]&15)<<2; break; case 2: outbuf[j++] = radixN[c|inbuf[i]>>6]; outbuf[j++] = radixN[inbuf[i]&63]; c = 0; } if (i%3) outbuf[j++] = radixN[c]; switch (i%3) { case 1: outbuf[j++] = pad; case 2: outbuf[j++] = pad; } outbuf[*len = j] = '\0'; } return(0); } char * radix_error(e) { switch (e) { case 0: return("Success"); case 1: return("Bad character in encoding"); case 2: return("Encoding not properly padded"); case 3: return("Decoded # of bits not a multiple of 8"); default: return("Unknown error"); } } #ifdef STANDALONE usage(s) char *s; { fprintf(stderr, "Usage: %s [ -d ] [ string ]\n", s); exit(2); } static int n; putbuf(inbuf, outbuf, len, decode) unsigned char inbuf[], outbuf[]; int len, decode; { int c; if (c = radix_encode(inbuf, outbuf, &len, decode)) { fprintf(stderr, "Couldn't %scode input: %s\n", decode ? "de" : "en", radix_error(c)); exit(1); } if (decode) write(1, outbuf, len); else for (c = 0; c < len;) { putchar(outbuf[c++]); if (++n%76 == 0) putchar('\n'); } } main(argc,argv) int argc; char *argv[]; { unsigned char *inbuf, *outbuf; int c, len = 0, decode = 0; extern int optind; while ((c = getopt(argc, argv, "d")) != -1) switch(c) { default: usage(argv[0]); case 'd': decode++; } switch (argc - optind) { case 0: inbuf = (unsigned char *) malloc(5); outbuf = (unsigned char *) malloc(5); while ((c = getchar()) != EOF) if (c != '\n') { inbuf[len++] = c; if (len == (decode ? 4 : 3)) { inbuf[len] = '\0'; putbuf(inbuf, outbuf, len, decode); len=0; } } if (len) { inbuf[len] = '\0'; putbuf(inbuf, outbuf, len, decode); } break; case 1: inbuf = (unsigned char *)argv[optind]; len = strlen(inbuf); outbuf = (unsigned char *) malloc((len * (decode?3:4)) / (decode?4:3) + 1); putbuf(inbuf, outbuf, len, decode); break; default: fprintf(stderr, "Only one argument allowed\n"); usage(argv[0]); } if (n%76) putchar('\n'); exit(0); } #endif /* STANDALONE */