\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;
}