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= 25517 };19 static char set64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";20 static char set32[] = "23456789abcdefghijkmnpqrstuvwxyz";21 static char set16[] = "0123456789ABCDEF0123456789abcdef";22 static char set10[] = "0123456789";24 static void25 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, 100000000074 };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 arithmetic89 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 mpint102 uitomp(mppow10[i], pow);103 uitomp(x, r);104 mpmul(b, pow, b);105 mpadd(b, r, b);106 if(i != 9)107 break;108 }109 mpfree(pow);110 mpfree(r);111 return a;112 }114 static char*115 from64(char *a, mpint *b)116 {117 char *buf = a;118 uchar *p;119 int n, m;121 for(; tab.t64[*(uchar*)a] != INVAL; a++)122 ;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;132 }134 static char*135 from32(char *a, mpint *b)136 {137 char *buf = a;138 uchar *p;139 int n, m;141 for(; tab.t64[*(uchar*)a] != INVAL; a++)142 ;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;152 }154 mpint*155 strtomp(char *a, char **pp, int base, mpint *b)156 {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;175 }176 break;177 }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;193 }195 // if no characters parsed, there wasn't a number to convert196 if(e == a)197 return nil;199 mpnorm(b);200 b->sign = sign;201 if(pp != nil)202 *pp = e;204 return b;205 }