\cat programming
int base64encode(char *ibuf, unsigned int ilen, char **obuf, unsigned int *olen, int ncols) { unsigned int i, j, k, l; char o[4], c, l2, l4, l6, *p; if(olen) *olen = 0; if(!ibuf || !ilen || !obuf) return 1; l = (ilen*8+23)/24*4+(ncols?((ilen*8+23)/24*4-1)/ncols:0); *obuf = p = (char *)malloc(l+1); if(!*obuf) return 1; l2 = (char)((1<<1)|1); l4 = (char)((l2<<2)|l2); l6 = (char)((l4<<2)|l2); k = 0; for(i=0; i<ilen; i+=3){ o[0] = (char)((ibuf[i]>>2)&l6); o[1] = (char)(((ibuf[i]&l2)<<4)| (i+1<ilen?((ibuf[i+1]>>4)&l4):0)); o[2] = (char)((i+1<ilen?((ibuf[i+1]&l4)<<2)| (i+2<ilen?(ibuf[i+2]>>6)&l2:0):64)); o[3] = (char)((i+2<ilen?ibuf[i+2]&l6:64)); for(j=0; j<4; j++){ c = o[j]; *p++ = (char)(c + (c<26?'A': (c<52?'a'-26: (c<62?'0'-52: (c<63?'+'-c: (c<64?'/'-c:'='-c)))))); k++; if(ncols && !(k%ncols)) *p++ = '\n'; } } *p = 0; if(olen) *olen = l; return 0; } int base64decode(char *ibuf, unsigned int ilen, char **obuf, unsigned int *olen) { unsigned int i, j, k; char c[4], ch, l2, l4, l6, *p; if(!ibuf || !ilen || !obuf || !olen) return 1; /* *olen = (ilen-ilen/77)/4*3; for(i=0; i<3; i++){ if(ibuf[ilen-i-1] != '=') break; } *olen -= i; */ *olen = ilen; *obuf = p = (char *)malloc(*olen+1); if(!*obuf){ *olen = 0; return 1; } l2 = (char)((1<<1)|1); l4 = (char)((l2<<2)|l2); l6 = (char)((l4<<2)|l2); k = 0; for(i=0; i<ilen; ){ for(j=0; j<4; j++){ ch = 0; for(; i<ilen; ){ ch = ibuf[i++]; if((ch>='A'&&ch<='Z')|| (ch>='a'&&ch<='z')|| (ch>='0'&&ch<='9')|| ch=='+'||ch=='/'||ch=='=') break; } if(i == ilen && !j) break; c[j] = (char)(ch + (ch>='A'&&ch<='Z'?-'A': (ch>='a'&&ch<='z'?-'a'+26: (ch>='0'&&ch<='9'?-'0'+52: (ch=='+'?-ch+62: (ch=='/'?-ch+63:-ch+64)))))); } if(!j) break; *p++ = (char)((c[0]<<2)|((c[1]>>4)&l2)); if(c[2] == 64) break; *p++ = (char)(((c[1]&l4)<<4)|((c[2]>>2)&l4)); if(c[3] == 64) break; *p++ = (char)(((c[2]&l2)<<6)|c[3]); } *p = 0; *olen = p-*obuf; return 0; }