|  | #include <lib9.h> | 
|  |  | 
|  | enum { | 
|  | INVAL=	255 | 
|  | }; | 
|  |  | 
|  | static uchar t64d[256] = { | 
|  | INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL, | 
|  | INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL, | 
|  | INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,   62,INVAL,INVAL,INVAL,   63, | 
|  | 52,   53,   54,   55,   56,   57,   58,   59,   60,   61,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL, | 
|  | INVAL,    0,    1,    2,    3,    4,    5,    6,    7,    8,    9,   10,   11,   12,   13,   14, | 
|  | 15,   16,   17,   18,   19,   20,   21,   22,   23,   24,   25,INVAL,INVAL,INVAL,INVAL,INVAL, | 
|  | INVAL,   26,   27,   28,   29,   30,   31,   32,   33,   34,   35,   36,   37,   38,   39,   40, | 
|  | 41,   42,   43,   44,   45,   46,   47,   48,   49,   50,   51,INVAL,INVAL,INVAL,INVAL,INVAL, | 
|  | INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL, | 
|  | INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL, | 
|  | INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL, | 
|  | INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL, | 
|  | INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL, | 
|  | INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL, | 
|  | INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL, | 
|  | INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL | 
|  | }; | 
|  | static char t64e[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | 
|  |  | 
|  | int | 
|  | dec64(uchar *out, int lim, char *in, int n) | 
|  | { | 
|  | ulong b24; | 
|  | uchar *start = out; | 
|  | uchar *e = out + lim; | 
|  | int i, c; | 
|  |  | 
|  | b24 = 0; | 
|  | i = 0; | 
|  | while(n-- > 0){ | 
|  |  | 
|  | c = t64d[*(uchar*)in++]; | 
|  | if(c == INVAL) | 
|  | continue; | 
|  | switch(i){ | 
|  | case 0: | 
|  | b24 = c<<18; | 
|  | break; | 
|  | case 1: | 
|  | b24 |= c<<12; | 
|  | break; | 
|  | case 2: | 
|  | b24 |= c<<6; | 
|  | break; | 
|  | case 3: | 
|  | if(out + 3 > e) | 
|  | goto exhausted; | 
|  |  | 
|  | b24 |= c; | 
|  | *out++ = b24>>16; | 
|  | *out++ = b24>>8; | 
|  | *out++ = b24; | 
|  | i = -1; | 
|  | break; | 
|  | } | 
|  | i++; | 
|  | } | 
|  | switch(i){ | 
|  | case 2: | 
|  | if(out + 1 > e) | 
|  | goto exhausted; | 
|  | *out++ = b24>>16; | 
|  | break; | 
|  | case 3: | 
|  | if(out + 2 > e) | 
|  | goto exhausted; | 
|  | *out++ = b24>>16; | 
|  | *out++ = b24>>8; | 
|  | break; | 
|  | } | 
|  | exhausted: | 
|  | return out - start; | 
|  | } | 
|  |  | 
|  | int | 
|  | enc64(char *out, int lim, uchar *in, int n) | 
|  | { | 
|  | int i; | 
|  | ulong b24; | 
|  | char *start = out; | 
|  | char *e = out + lim; | 
|  |  | 
|  | for(i = n/3; i > 0; i--){ | 
|  | b24 = (*in++)<<16; | 
|  | b24 |= (*in++)<<8; | 
|  | b24 |= *in++; | 
|  | if(out + 4 >= e) | 
|  | goto exhausted; | 
|  | *out++ = t64e[(b24>>18)]; | 
|  | *out++ = t64e[(b24>>12)&0x3f]; | 
|  | *out++ = t64e[(b24>>6)&0x3f]; | 
|  | *out++ = t64e[(b24)&0x3f]; | 
|  | } | 
|  |  | 
|  | switch(n%3){ | 
|  | case 2: | 
|  | b24 = (*in++)<<16; | 
|  | b24 |= (*in)<<8; | 
|  | if(out + 4 >= e) | 
|  | goto exhausted; | 
|  | *out++ = t64e[(b24>>18)]; | 
|  | *out++ = t64e[(b24>>12)&0x3f]; | 
|  | *out++ = t64e[(b24>>6)&0x3f]; | 
|  | *out++ = '='; | 
|  | break; | 
|  | case 1: | 
|  | b24 = (*in)<<16; | 
|  | if(out + 4 >= e) | 
|  | goto exhausted; | 
|  | *out++ = t64e[(b24>>18)]; | 
|  | *out++ = t64e[(b24>>12)&0x3f]; | 
|  | *out++ = '='; | 
|  | *out++ = '='; | 
|  | break; | 
|  | } | 
|  | exhausted: | 
|  | *out = 0; | 
|  | return out - start; | 
|  | } |