19a747e4fSDavid du Colombier #include <u.h>
29a747e4fSDavid du Colombier #include <libc.h>
39a747e4fSDavid du Colombier
49a747e4fSDavid du Colombier enum {
59a747e4fSDavid du Colombier INVAL= 255
69a747e4fSDavid du Colombier };
79a747e4fSDavid du Colombier
89a747e4fSDavid du Colombier static uchar t64d[256] = {
99a747e4fSDavid du Colombier INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
109a747e4fSDavid du Colombier INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
119a747e4fSDavid du Colombier INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL, 62,INVAL,INVAL,INVAL, 63,
129a747e4fSDavid du Colombier 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
139a747e4fSDavid du Colombier INVAL, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
149a747e4fSDavid du Colombier 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,INVAL,INVAL,INVAL,INVAL,INVAL,
159a747e4fSDavid du Colombier INVAL, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
169a747e4fSDavid du Colombier 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,INVAL,INVAL,INVAL,INVAL,INVAL,
179a747e4fSDavid du Colombier INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
189a747e4fSDavid du Colombier INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
199a747e4fSDavid du Colombier INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
209a747e4fSDavid du Colombier INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
219a747e4fSDavid du Colombier INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
229a747e4fSDavid du Colombier INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
239a747e4fSDavid du Colombier INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
249a747e4fSDavid du Colombier INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL
259a747e4fSDavid du Colombier };
269a747e4fSDavid du Colombier static char t64e[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
279a747e4fSDavid du Colombier
289a747e4fSDavid du Colombier int
dec64(uchar * out,int lim,char * in,int n)299a747e4fSDavid du Colombier dec64(uchar *out, int lim, char *in, int n)
309a747e4fSDavid du Colombier {
319a747e4fSDavid du Colombier ulong b24;
329a747e4fSDavid du Colombier uchar *start = out;
339a747e4fSDavid du Colombier uchar *e = out + lim;
349a747e4fSDavid du Colombier int i, c;
359a747e4fSDavid du Colombier
369a747e4fSDavid du Colombier b24 = 0;
379a747e4fSDavid du Colombier i = 0;
389a747e4fSDavid du Colombier while(n-- > 0){
399a747e4fSDavid du Colombier
409a747e4fSDavid du Colombier c = t64d[*(uchar*)in++];
419a747e4fSDavid du Colombier if(c == INVAL)
429a747e4fSDavid du Colombier continue;
439a747e4fSDavid du Colombier switch(i){
449a747e4fSDavid du Colombier case 0:
459a747e4fSDavid du Colombier b24 = c<<18;
469a747e4fSDavid du Colombier break;
479a747e4fSDavid du Colombier case 1:
489a747e4fSDavid du Colombier b24 |= c<<12;
499a747e4fSDavid du Colombier break;
509a747e4fSDavid du Colombier case 2:
519a747e4fSDavid du Colombier b24 |= c<<6;
529a747e4fSDavid du Colombier break;
539a747e4fSDavid du Colombier case 3:
549a747e4fSDavid du Colombier if(out + 3 > e)
559a747e4fSDavid du Colombier goto exhausted;
569a747e4fSDavid du Colombier
579a747e4fSDavid du Colombier b24 |= c;
589a747e4fSDavid du Colombier *out++ = b24>>16;
599a747e4fSDavid du Colombier *out++ = b24>>8;
609a747e4fSDavid du Colombier *out++ = b24;
619a747e4fSDavid du Colombier i = -1;
629a747e4fSDavid du Colombier break;
639a747e4fSDavid du Colombier }
649a747e4fSDavid du Colombier i++;
659a747e4fSDavid du Colombier }
669a747e4fSDavid du Colombier switch(i){
679a747e4fSDavid du Colombier case 2:
689a747e4fSDavid du Colombier if(out + 1 > e)
699a747e4fSDavid du Colombier goto exhausted;
709a747e4fSDavid du Colombier *out++ = b24>>16;
719a747e4fSDavid du Colombier break;
729a747e4fSDavid du Colombier case 3:
739a747e4fSDavid du Colombier if(out + 2 > e)
749a747e4fSDavid du Colombier goto exhausted;
759a747e4fSDavid du Colombier *out++ = b24>>16;
769a747e4fSDavid du Colombier *out++ = b24>>8;
779a747e4fSDavid du Colombier break;
789a747e4fSDavid du Colombier }
799a747e4fSDavid du Colombier exhausted:
809a747e4fSDavid du Colombier return out - start;
819a747e4fSDavid du Colombier }
829a747e4fSDavid du Colombier
839a747e4fSDavid du Colombier int
enc64(char * out,int lim,uchar * in,int n)849a747e4fSDavid du Colombier enc64(char *out, int lim, uchar *in, int n)
859a747e4fSDavid du Colombier {
869a747e4fSDavid du Colombier int i;
879a747e4fSDavid du Colombier ulong b24;
889a747e4fSDavid du Colombier char *start = out;
899a747e4fSDavid du Colombier char *e = out + lim;
909a747e4fSDavid du Colombier
919a747e4fSDavid du Colombier for(i = n/3; i > 0; i--){
929a747e4fSDavid du Colombier b24 = (*in++)<<16;
939a747e4fSDavid du Colombier b24 |= (*in++)<<8;
949a747e4fSDavid du Colombier b24 |= *in++;
95*3ff48bf5SDavid du Colombier if(out + 4 >= e)
969a747e4fSDavid du Colombier goto exhausted;
979a747e4fSDavid du Colombier *out++ = t64e[(b24>>18)];
989a747e4fSDavid du Colombier *out++ = t64e[(b24>>12)&0x3f];
999a747e4fSDavid du Colombier *out++ = t64e[(b24>>6)&0x3f];
1009a747e4fSDavid du Colombier *out++ = t64e[(b24)&0x3f];
1019a747e4fSDavid du Colombier }
1029a747e4fSDavid du Colombier
1039a747e4fSDavid du Colombier switch(n%3){
1049a747e4fSDavid du Colombier case 2:
1059a747e4fSDavid du Colombier b24 = (*in++)<<16;
1069a747e4fSDavid du Colombier b24 |= (*in)<<8;
1079a747e4fSDavid du Colombier if(out + 4 >= e)
1089a747e4fSDavid du Colombier goto exhausted;
1099a747e4fSDavid du Colombier *out++ = t64e[(b24>>18)];
1109a747e4fSDavid du Colombier *out++ = t64e[(b24>>12)&0x3f];
1119a747e4fSDavid du Colombier *out++ = t64e[(b24>>6)&0x3f];
1129a747e4fSDavid du Colombier *out++ = '=';
1139a747e4fSDavid du Colombier break;
1149a747e4fSDavid du Colombier case 1:
1159a747e4fSDavid du Colombier b24 = (*in)<<16;
1169a747e4fSDavid du Colombier if(out + 4 >= e)
1179a747e4fSDavid du Colombier goto exhausted;
1189a747e4fSDavid du Colombier *out++ = t64e[(b24>>18)];
1199a747e4fSDavid du Colombier *out++ = t64e[(b24>>12)&0x3f];
1209a747e4fSDavid du Colombier *out++ = '=';
1219a747e4fSDavid du Colombier *out++ = '=';
1229a747e4fSDavid du Colombier break;
1239a747e4fSDavid du Colombier }
1249a747e4fSDavid du Colombier exhausted:
1259a747e4fSDavid du Colombier *out = 0;
1269a747e4fSDavid du Colombier return out - start;
1279a747e4fSDavid du Colombier }
128