xref: /inferno-os/libkern/u64.c (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
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
dec64(uchar * out,int lim,char * in,int n)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
enc64(char * out,int lim,uchar * in,int n)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 }
127