int DecodeShortV3(const char* serial, bool level10, unsigned char* dest, int dest_len) { char keybytes_[512]; char* kb=keybytes_; char* keybytes=keybytes_; char* k1; char* k2; bool keystring=false; int keylength; const char* udigits="0123456789ABCDEFGHJKMNPQRTUVWXYZ"; const char* ldigits="0123456789abcdefghjkmnpqrtuvwxyz"; const char* c=serial; const char* p; unsigned char value=0; unsigned char firstdigit=1; BigInt n, n2, n3; n=BigInt_Create(); n2=BigInt_Create(); n3=BigInt_Create(); int level=0; if(level10) level=10; if(serial==0 || serial[0]==0) { return 0; } while(c[0]) { p=strchr(udigits, c[0]); //first the current serial character in udigits if(p) { value=p-udigits; } else { p=strchr(ldigits, c[0]); //first the current character in ldigits if(p) { value=p-ldigits; } else if(c[0]=='i' || c[0]=='I' || c[0]=='l' || c[0]=='L') { value=1; } else if(c[0]=='o' || c[0]=='O') { value=0; } else if(c[0]=='s' || c[0]=='S') { value=5; } else { value=32; } } c++; if(value<32) //must be base32 { if(firstdigit) //ignore the first key character { if(level==10) { /* All level 10 keys start with the digit 1. It doesn't convey any information other than the fact that they're level 10 keys; discard it. */ //KeyString starts with 3 if(value==3) { value=0; keystring=true; //TODO: remove? } if(value!=0) { value=0; firstdigit=0; } } else { //KeyString starts with 3 if(value==3) { value=0; keystring=true; //TODO: remove? } if(value!=0 && value>=16) { value-=16; firstdigit=0; } } } BigInt_Shift(n, 5, n2); BigInt_SetU(n3, value); BigInt_Add(n2, n3, n); } } //end of loop //Spit out the bytes, in reverse order. BigInt_Set(n3, 0xFF); if(level==10) { while(BigInt_Compare(n, BigInt_One())>0) { BigInt_And(n, n3, n2); kb[0]=(unsigned char)BigInt_GetU(n2); kb++; BigInt_Shift(n, -8, n2); BigInt_Copy(n, n2); } } else { while(BigInt_Compare(n, BigInt_Zero())!=0) { BigInt_And(n, n3, n2); kb[0]=(unsigned char)BigInt_GetU(n2); kb++; BigInt_Shift(n, -8, n2); BigInt_Copy(n, n2); } } if((kb-keybytes)%2) //if the length / 2 has a remainder { kb[0]=0; //discard last byte? kb++; } /* Reverse digits in keybytes */ k1=keybytes; k2=kb-1; while(k1<k2) { char t=k1[0]; k1[0]=k2[0]; k2[0]=t; k2--; k1++; } BigInt_Destroy(n3); BigInt_Destroy(n2); BigInt_Destroy(n); keylength=kb-keybytes; memset(dest, 0, dest_len); memcpy(dest, keybytes, keylength); return keylength; }
int BigInt_Divide(BigInt a, BigInt b, BigInt answer, BigInt remainder) { //TODO: fix something here (memleak temp1 or t) int compare, i, signa, signb; WORKING_DIGIT high, low, t; BigInt temp1, temp2; temp1=BigInt_Create(); temp2=BigInt_Create(); signa=a->negative; a->negative=0; signb=b->negative; b->negative=0; /* Check for divide-by-zero, it's not allowed */ if(b->length==1 && b->digits[0]==0) return 0; /* Compare a and b, to see if we can take a shortcut */ compare=BigInt_Compare_SignOptional(a, b, 1); if(compare<0) { BigInt_Set(answer, 0); BigInt_Copy(remainder, a); return 1; } else if(compare==0) { BigInt_Set(answer, 1); BigInt_Set(remainder, 0); return 1; } BigInt_Realloc(answer, a->length, 0); BigInt_Set(remainder, 0); for(i=1; i<=a->length; ++i) { /* remainder=(remainder<<BITS_PER_DIGIT)+a->digits[a->length-i]; */ BigInt_Copy(temp1, remainder); BigInt_Shift(temp1, BITS_PER_DIGIT, remainder); remainder->digits[0]=a->digits[a->length-i]; if(BigInt_Compare_SignOptional(remainder, b, 1)>=0) { high=OVERFLOW_DIGIT; low=0; while(low<high) { t=((high-low)/2)+low; /* if ((b*t)>remainder) high=t; else low=t+1; */ BigInt_Set(temp2, t); BigInt_Multiply(b, temp2, temp1); if(BigInt_Compare(temp1, remainder)>0) high=t; else low=t+1; } t=low-1; answer->digits[a->length-i]=(DIGIT)(t); /* remainder=remainder-(b*t) */ BigInt_Set(temp2, t); BigInt_Multiply(b, temp2, temp1); BigInt_Subtract(remainder, temp1, temp2); BigInt_Copy(remainder, temp2); } else answer->digits[a->length-i]=0; } a->negative=signa; b->negative=signb; answer->negative=(a->negative ^ b->negative); BigInt_FindMSD(answer); BigInt_Destroy(temp2); BigInt_Destroy(temp1); return 1; }
char* EncodeShortV3(unsigned char* keybytes, int keylength, bool level10) { char* cc; char* shortv3digits=(char*)"0123456789ABCDEFGHJKMNPQRTUVWXYZ"; static char retval[512]=""; int level=0; int dcount; int nn; if(level10) level=29; strcpy(retval, ""); BigInt n=BigInt_Create(); BigInt t1=BigInt_Create(); BigInt t2=BigInt_Create(); if(level==29) BigInt_Set(n, 1); for(int x=0; x<keylength; ++x) { BigInt_Shift(n, 8, t1); BigInt_SetU(t2, keybytes[x]); BigInt_Add(t1, t2, n); } cc=retval; dcount=6; while(BigInt_Compare(n, BigInt_Zero())!=0) { BigInt_SetU(t2, 32); BigInt_Modulus(n, t2, t1); nn=BigInt_Get(t1); BigInt_Shift(n, -5, t2); BigInt_Copy(n, t2); if(level==29) { *cc++=shortv3digits[nn]; if(--dcount==0) { dcount=6; *cc++='-'; } } else { if(BigInt_Compare(n, BigInt_Zero())==0) { if(nn<16) { *cc++=shortv3digits[nn+16]; --dcount; } else { *cc++=shortv3digits[nn]; if(--dcount==0) { dcount=6; *cc++='-'; } *cc++=shortv3digits[16]; --dcount; } } else { *cc++=shortv3digits[nn]; if(--dcount==0) { dcount=6; *cc++='-'; } } } } if(level==29) { *cc++='1'; --dcount; } while(dcount-->0) *cc++='0'; *cc=0; mystrrev(retval); BigInt_Destroy(t2); BigInt_Destroy(t1); BigInt_Destroy(n); return retval; }