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