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= 25516 };18 static char set64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";19 static char set32[] = "23456789abcdefghijkmnpqrstuvwxyz";20 static char set16[] = "0123456789ABCDEF0123456789abcdef";21 static char set10[] = "0123456789";23 static void24 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, 100000000073 };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;107 }108 mpfree(pow);109 mpfree(r);110 return a;111 }113 static char*114 from64(char *a, mpint *b)115 {116 char *buf = a;117 uchar *p;118 int n, m;120 for(; tab.t64[*(uchar*)a] != INVAL; a++)121 ;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;131 }133 static char*134 from32(char *a, mpint *b)135 {136 char *buf = a;137 uchar *p;138 int n, m;140 for(; tab.t64[*(uchar*)a] != INVAL; a++)141 ;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;151 }153 mpint*154 strtomp(char *a, char **pp, int base, mpint *b)155 {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;174 }175 break;176 }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;192 }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;204 }