signed long BigInt_Get(BigInt n) { signed long value=BigInt_GetU(n); if(value<0) value=-value; if(n->negative) value=-value; return value; }
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; }