9base

revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log | Files | Refs | README | LICENSE

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 }