Blob


1 #include "os.h"
2 #include <mp.h>
3 #include "dat.h"
5 static struct {
6 int inited;
8 uchar t64[256];
9 uchar t32[256];
10 uchar t16[256];
11 uchar t10[256];
12 } tab;
14 enum {
15 INVAL= 255
16 };
18 static char set64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
19 static char set32[] = "23456789abcdefghijkmnpqrstuvwxyz";
20 static char set16[] = "0123456789ABCDEF0123456789abcdef";
21 static char set10[] = "0123456789";
23 static void
24 init(void)
25 {
26 char *p;
28 memset(tab.t64, INVAL, sizeof(tab.t64));
29 memset(tab.t32, INVAL, sizeof(tab.t32));
30 memset(tab.t16, INVAL, sizeof(tab.t16));
31 memset(tab.t10, INVAL, sizeof(tab.t10));
33 for(p = set64; *p; p++)
34 tab.t64[(uchar)*p] = p-set64;
35 for(p = set32; *p; p++)
36 tab.t32[(uchar)*p] = p-set32;
37 for(p = set16; *p; p++)
38 tab.t16[(uchar)*p] = (p-set16)%16;
39 for(p = set10; *p; p++)
40 tab.t10[(uchar)*p] = (p-set10);
42 tab.inited = 1;
43 }
45 static char*
46 from16(char *a, mpint *b)
47 {
48 char *p, *next;
49 int i;
50 mpdigit x;
52 b->top = 0;
53 for(p = a; *p; p++)
54 if(tab.t16[*(uchar*)p] == INVAL)
55 break;
56 mpbits(b, (p-a)*4);
57 b->top = 0;
58 next = p;
59 while(p > a){
60 x = 0;
61 for(i = 0; i < Dbits; i += 4){
62 if(p <= a)
63 break;
64 x |= tab.t16[*(uchar*)--p]<<i;
65 }
66 b->p[b->top++] = x;
67 }
68 return next;
69 }
71 static ulong mppow10[] = {
72 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000
73 };
75 static char*
76 from10(char *a, mpint *b)
77 {
78 ulong x, y;
79 mpint *pow, *r;
80 int i;
82 pow = mpnew(0);
83 r = mpnew(0);
85 b->top = 0;
86 for(;;){
87 /* do a billion at a time in native arithmetic */
88 x = 0;
89 for(i = 0; i < 9; i++){
90 y = tab.t10[*(uchar*)a];
91 if(y == INVAL)
92 break;
93 a++;
94 x *= 10;
95 x += y;
96 }
97 if(i == 0)
98 break;
100 /* accumulate into mpint */
101 uitomp(mppow10[i], pow);
102 uitomp(x, r);
103 mpmul(b, pow, b);
104 mpadd(b, r, b);
105 if(i != 9)
106 break;
108 mpfree(pow);
109 mpfree(r);
110 return a;
113 static char*
114 from64(char *a, mpint *b)
116 char *buf = a;
117 uchar *p;
118 int n, m;
120 for(; tab.t64[*(uchar*)a] != INVAL; a++)
122 n = a-buf;
123 mpbits(b, n*6);
124 p = malloc(n);
125 if(p == nil)
126 return a;
127 m = dec64(p, n, buf, n);
128 betomp(p, m, b);
129 free(p);
130 return a;
133 static char*
134 from32(char *a, mpint *b)
136 char *buf = a;
137 uchar *p;
138 int n, m;
140 for(; tab.t64[*(uchar*)a] != INVAL; a++)
142 n = a-buf;
143 mpbits(b, n*5);
144 p = malloc(n);
145 if(p == nil)
146 return a;
147 m = dec32(p, n, buf, n);
148 betomp(p, m, b);
149 free(p);
150 return a;
153 mpint*
154 strtomp(char *a, char **pp, int base, mpint *b)
156 int sign;
157 char *e;
159 if(b == nil)
160 b = mpnew(0);
162 if(tab.inited == 0)
163 init();
165 while(*a==' ' || *a=='\t')
166 a++;
168 sign = 1;
169 for(;; a++){
170 switch(*a){
171 case '-':
172 sign *= -1;
173 continue;
175 break;
178 switch(base){
179 case 10:
180 e = from10(a, b);
181 break;
182 default:
183 case 16:
184 e = from16(a, b);
185 break;
186 case 32:
187 e = from32(a, b);
188 break;
189 case 64:
190 e = from64(a, b);
191 break;
194 /* if no characters parsed, there wasn't a number to convert */
195 if(e == a)
196 return nil;
198 mpnorm(b);
199 b->sign = sign;
200 if(pp != nil)
201 *pp = e;
203 return b;