u64.c (3267B)
1 #include <lib9.h> 2 3 enum { 4 INVAL= 255 5 }; 6 7 static uchar t64d[256] = { 8 INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL, 9 INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL, 10 INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL, 62,INVAL,INVAL,INVAL, 63, 11 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL, 12 INVAL, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 13 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,INVAL,INVAL,INVAL,INVAL,INVAL, 14 INVAL, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 15 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,INVAL,INVAL,INVAL,INVAL,INVAL, 16 INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL, 17 INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL, 18 INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL, 19 INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL, 20 INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL, 21 INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL, 22 INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL, 23 INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL 24 }; 25 static char t64e[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 26 27 int 28 dec64(uchar *out, int lim, char *in, int n) 29 { 30 ulong b24; 31 uchar *start = out; 32 uchar *e = out + lim; 33 int i, c; 34 35 b24 = 0; 36 i = 0; 37 while(n-- > 0){ 38 39 c = t64d[*(uchar*)in++]; 40 if(c == INVAL) 41 continue; 42 switch(i){ 43 case 0: 44 b24 = c<<18; 45 break; 46 case 1: 47 b24 |= c<<12; 48 break; 49 case 2: 50 b24 |= c<<6; 51 break; 52 case 3: 53 if(out + 3 > e) 54 goto exhausted; 55 56 b24 |= c; 57 *out++ = b24>>16; 58 *out++ = b24>>8; 59 *out++ = b24; 60 i = -1; 61 break; 62 } 63 i++; 64 } 65 switch(i){ 66 case 2: 67 if(out + 1 > e) 68 goto exhausted; 69 *out++ = b24>>16; 70 break; 71 case 3: 72 if(out + 2 > e) 73 goto exhausted; 74 *out++ = b24>>16; 75 *out++ = b24>>8; 76 break; 77 } 78 exhausted: 79 return out - start; 80 } 81 82 int 83 enc64(char *out, int lim, uchar *in, int n) 84 { 85 int i; 86 ulong b24; 87 char *start = out; 88 char *e = out + lim; 89 90 for(i = n/3; i > 0; i--){ 91 b24 = (*in++)<<16; 92 b24 |= (*in++)<<8; 93 b24 |= *in++; 94 if(out + 4 >= e) 95 goto exhausted; 96 *out++ = t64e[(b24>>18)]; 97 *out++ = t64e[(b24>>12)&0x3f]; 98 *out++ = t64e[(b24>>6)&0x3f]; 99 *out++ = t64e[(b24)&0x3f]; 100 } 101 102 switch(n%3){ 103 case 2: 104 b24 = (*in++)<<16; 105 b24 |= (*in)<<8; 106 if(out + 4 >= e) 107 goto exhausted; 108 *out++ = t64e[(b24>>18)]; 109 *out++ = t64e[(b24>>12)&0x3f]; 110 *out++ = t64e[(b24>>6)&0x3f]; 111 *out++ = '='; 112 break; 113 case 1: 114 b24 = (*in)<<16; 115 if(out + 4 >= e) 116 goto exhausted; 117 *out++ = t64e[(b24>>18)]; 118 *out++ = t64e[(b24>>12)&0x3f]; 119 *out++ = '='; 120 *out++ = '='; 121 break; 122 } 123 exhausted: 124 *out = 0; 125 return out - start; 126 }