Blob


1 #include "os.h"
2 #include <mp.h>
3 #include <libsec.h>
4 #include "dat.h"
6 static struct {
7 int inited;
9 uchar t64[256];
10 uchar t32[256];
11 uchar t16[256];
12 uchar t10[256];
13 } tab;
15 enum {
16 INVAL= 255
17 };
19 static char set64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
20 static char set32[] = "23456789abcdefghijkmnpqrstuvwxyz";
21 static char set16[] = "0123456789ABCDEF0123456789abcdef";
22 static char set10[] = "0123456789";
24 static void
25 init(void)
26 {
27 char *p;
29 memset(tab.t64, INVAL, sizeof(tab.t64));
30 memset(tab.t32, INVAL, sizeof(tab.t32));
31 memset(tab.t16, INVAL, sizeof(tab.t16));
32 memset(tab.t10, INVAL, sizeof(tab.t10));
34 for(p = set64; *p; p++)
35 tab.t64[(uchar)*p] = p-set64;
36 for(p = set32; *p; p++)
37 tab.t32[(uchar)*p] = p-set32;
38 for(p = set16; *p; p++)
39 tab.t16[(uchar)*p] = (p-set16)%16;
40 for(p = set10; *p; p++)
41 tab.t10[(uchar)*p] = (p-set10);
43 tab.inited = 1;
44 }
46 static char*
47 from16(char *a, mpint *b)
48 {
49 char *p, *next;
50 int i;
51 mpdigit x;
53 b->top = 0;
54 for(p = a; *p; p++)
55 if(tab.t16[*(uchar*)p] == INVAL)
56 break;
57 mpbits(b, (p-a)*4);
58 b->top = 0;
59 next = p;
60 while(p > a){
61 x = 0;
62 for(i = 0; i < Dbits; i += 4){
63 if(p <= a)
64 break;
65 x |= tab.t16[*(uchar*)--p]<<i;
66 }
67 b->p[b->top++] = x;
68 }
69 return next;
70 }
72 static ulong mppow10[] = {
73 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000
74 };
76 static char*
77 from10(char *a, mpint *b)
78 {
79 ulong x, y;
80 mpint *pow, *r;
81 int i;
83 pow = mpnew(0);
84 r = mpnew(0);
86 b->top = 0;
87 for(;;){
88 // do a billion at a time in native arithmetic
89 x = 0;
90 for(i = 0; i < 9; i++){
91 y = tab.t10[*(uchar*)a];
92 if(y == INVAL)
93 break;
94 a++;
95 x *= 10;
96 x += y;
97 }
98 if(i == 0)
99 break;
101 // accumulate into mpint
102 uitomp(mppow10[i], pow);
103 uitomp(x, r);
104 mpmul(b, pow, b);
105 mpadd(b, r, b);
106 if(i != 9)
107 break;
109 mpfree(pow);
110 mpfree(r);
111 return a;
114 static char*
115 from64(char *a, mpint *b)
117 char *buf = a;
118 uchar *p;
119 int n, m;
121 for(; tab.t64[*(uchar*)a] != INVAL; a++)
123 n = a-buf;
124 mpbits(b, n*6);
125 p = malloc(n);
126 if(p == nil)
127 return a;
128 m = dec64(p, n, buf, n);
129 betomp(p, m, b);
130 free(p);
131 return a;
134 static char*
135 from32(char *a, mpint *b)
137 char *buf = a;
138 uchar *p;
139 int n, m;
141 for(; tab.t64[*(uchar*)a] != INVAL; a++)
143 n = a-buf;
144 mpbits(b, n*5);
145 p = malloc(n);
146 if(p == nil)
147 return a;
148 m = dec32(p, n, buf, n);
149 betomp(p, m, b);
150 free(p);
151 return a;
154 mpint*
155 strtomp(char *a, char **pp, int base, mpint *b)
157 int sign;
158 char *e;
160 if(b == nil)
161 b = mpnew(0);
163 if(tab.inited == 0)
164 init();
166 while(*a==' ' || *a=='\t')
167 a++;
169 sign = 1;
170 for(;; a++){
171 switch(*a){
172 case '-':
173 sign *= -1;
174 continue;
176 break;
179 switch(base){
180 case 10:
181 e = from10(a, b);
182 break;
183 default:
184 case 16:
185 e = from16(a, b);
186 break;
187 case 32:
188 e = from32(a, b);
189 break;
190 case 64:
191 e = from64(a, b);
192 break;
195 // if no characters parsed, there wasn't a number to convert
196 if(e == a)
197 return nil;
199 mpnorm(b);
200 b->sign = sign;
201 if(pp != nil)
202 *pp = e;
204 return b;