📄 berdecoder.cpp
字号:
// BERDecoder.cpp: implementation of the CBERDecoder class.////////////////////////////////////////////////////////////////////////#include "BERDecoder.h"#include "ASN1Tag.h"#include <time.h>#include <math.h>//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////namespace ASN1{ CBERDecoder::CBERDecoder() { } typedef unsigned short PlatWord; typedef unsigned long PlatDoubleWord; const int PlatDigits = (8*sizeof(PlatWord)); const PlatDoubleWord WordBase = ((PlatDoubleWord)1)<<PlatDigits; class BigInteger { public: inline BigInteger(); inline bool operator==(const BigInteger& aOther) const; inline bool operator!=(const BigInteger& aOther) const; BigInteger(const string& anInteger); // Create an integer BigInteger(const BigInteger& aOther) : digits(aOther.digits), negative(aOther.negative) {} string ToString() const; inline void Add(const BigInteger& aSource); inline void MultiplyAdd(const BigInteger& aX, const BigInteger& aY); inline void Negate() {negative = !negative;}; protected: typedef PlatWord ElementType; // two bytes typedef PlatDoubleWord DoubleElementType; // four bytes enum { WordBits = PlatDigits}; inline void Normalize(); inline void AddWord(PlatWord aTerm); inline void MultWord(PlatWord aFactor); inline void DivideWord(PlatDoubleWord aNumber, PlatDoubleWord& aCarry); private: vector<ElementType> digits; bool negative; }; inline BigInteger::BigInteger() : negative(false) { digits.push_back(0); } inline bool BigInteger::operator==(const BigInteger& aOther) const { return (negative == aOther.negative && digits == aOther.digits); } inline bool BigInteger::operator!=(const BigInteger& aOther) const { return !(*this == aOther); } inline void BigInteger::Normalize() { int nr=digits.size(); while (nr > 1 && digits[nr-1] == 0) { digits.pop_back(); nr--; } } inline void BigInteger::AddWord(PlatWord aTerm) { if (digits.size() == 0) digits.push_back(0); digits.push_back(0); DoubleElementType carry = 0; { DoubleElementType accu; accu = digits[0]; accu += aTerm; accu += carry; digits[0] = (ElementType)(accu); carry = (accu >> WordBits); } int i=1; while (carry) { DoubleElementType accu; accu = digits[i]; accu += carry; digits[i] = (ElementType)(accu); carry = (accu >> WordBits); i++; } Normalize(); } inline void BigInteger::MultWord(PlatWord aFactor) { unsigned i; digits.push_back(0); DoubleElementType carry = 0; for (i=0;i<digits.size();i++) { DoubleElementType accu; accu = digits[i]; accu *= aFactor; accu += carry; digits[i] = (ElementType)(accu); carry = (accu >> WordBits); }// assert(carry == 0); Normalize(); } inline void BigInteger::DivideWord(PlatDoubleWord aNumber, PlatDoubleWord& aCarry) { PlatDoubleWord carry=0; int i; int nr=digits.size(); for (i=nr-1;i>=0;i--) { PlatDoubleWord word = ((carry*WordBase)+((PlatDoubleWord)(digits[i]))); PlatWord digit = (PlatWord)(word / aNumber); PlatWord newCarry= (PlatWord)(word % aNumber); digits[i] = digit; carry= newCarry; } //carry now is the remainder aCarry = carry; Normalize(); } inline void BigInteger::Add(const BigInteger& aSource) { while (digits.size() < aSource.digits.size()) digits.push_back(0); digits.push_back(0); unsigned i; DoubleElementType carry = 0; for (i=0;i<aSource.digits.size();i++) { DoubleElementType accu; accu = digits[i]; accu += aSource.digits[i]; accu += carry; digits[i] = (ElementType)(accu); carry = (accu>>WordBits); } while (carry) { DoubleElementType accu; accu = digits[i]; accu += carry; digits[i] = (ElementType)(accu); carry = (accu>>WordBits); i++; } Normalize(); } inline void BigInteger::MultiplyAdd(const BigInteger& aX, const BigInteger& aY) { unsigned i,j; for (i=aX.digits.size()+aY.digits.size()-digits.size();i>0;--i) digits.push_back(0); for (i=0;i<aX.digits.size();i++) { DoubleElementType carry = 0; DoubleElementType factor = aX.digits[i]; for (j=0;j<aY.digits.size();j++) { DoubleElementType accu; accu = digits[i+j] + ((DoubleElementType)aY.digits[j])*factor + carry; digits[i+j] = (ElementType)(accu); carry = (accu>>WordBits); } while (carry) { DoubleElementType accu; accu = digits[i+j] + carry; digits[i+j] = (ElementType)(accu); carry = (accu>>WordBits); j++; }// assert(carry == 0); } Normalize(); } BigInteger::BigInteger(const string& anInteger) { unsigned i=0; negative = false; if (anInteger[0] == '-') { negative = true; i++; } for (;i<anInteger.size();++i) { int digit = anInteger[i]-'0'; MultWord(10); AddWord(digit); } } string BigInteger::ToString() const { BigInteger zero; if (*this == zero) return "0"; string result; BigInteger number(*this); while (number != zero) { PlatDoubleWord digit; number.DivideWord(10, digit); result+= digit;//.push_back(digit); } int i,nr=result.size(); for (i=(nr>>1)-1;i>=0;--i) { char swp = result[i]; result[i] = '0' + result[result.size()-i-1]; result[result.size()-i-1] = '0' + swp; } if (nr&1) result[(nr>>1)] += '0'; if (negative) result.insert(0,"-",0,1); return result; } bool CBigInt::Decode(const char* szBinary, int nLength, string& pOutString) { char szHex[40]; int all=0; for(int i=0;i<nLength;i++) { szHex[all++] = (szBinary[i] & 0xF0) >>4; szHex[all++] = (szBinary[i] & 0x0F); } BigInteger iSum("0"); BigInteger iResult("0"); BigInteger iHex("16"); char tt[34]; for(int j=0;j<all;j++) { _snprintf(tt, 34, "%d", szHex[j]); BigInteger hex(tt); iResult=BigInteger("0"); iResult.MultiplyAdd(iSum, iHex); iResult.Add(hex); iSum = iResult; } pOutString = iSum.ToString(); return true; } //// bool CBERDecoder::decodeBool(const char* szInputStream, int nLength, bool &out) { out = szInputStream[0] != 0; return true; } bool CBERDecoder::decodeOctetString(const char* szInputStream, int nLength, char*& out,int& count) { if(nLength < 0) return false; if(nLength == 0) { out = NULL; count = 0; return true; } out = new char[nLength]; memcpy(out, szInputStream, nLength); count = nLength; return true; } bool CBERDecoder::decodeIpAddress(const char* szInputStream, int nLength, String &out) { out = ""; char tmp[46]; for(int i=0;i<nLength;i++) { if(i>0) out += "."; _snprintf(tmp, 46, "%d",(unsigned char)szInputStream[i]); out += tmp; } return true; } /* bool CBERDecoder::decodeInteger(const char* szInputStream, int nLength, int &out) { out = 0; if(nLength < 0 || nLength > 4) return false; if(nLength == 4) { out = (szInputStream[0] & 0xff) << 24 | (szInputStream[1] & 0xff) << 16 | (szInputStream[2] & 0xff) << 8 | szInputStream[3] & 0xff; } else if(nLength == 3) { out = (szInputStream[0] & 0xff) << 16 | (szInputStream[1] & 0xff) << 8 | szInputStream[2] & 0xff; out <<= 8; out >>= 8; } else if(nLength == 2) { out = (szInputStream[0] & 0xff) << 8 | szInputStream[1] & 0xff; out <<= 16; out >>= 16; } else { out = szInputStream[0]; } return true; } */ bool CBERDecoder::decodeObjId(const char* szInputStream, int nLength, int* &out, int &count) { int *ObjIds = new int[(nLength - 1) * 4 + 2]; int k = szInputStream[0]; if(k < 40) ObjIds[1] = k; else { if(k < 80) { ObjIds[0] = 1; ObjIds[1] = k - 40; } else { ObjIds[0] = 2; ObjIds[1] = k - 80; } } int l = 1; k = 2; for(; l < nLength; l = parseComponent(szInputStream, l, ObjIds, k++)) ; count = k; out = new int [count]; for(int i=0;i<count;i++) out[i] = ObjIds[i]; delete []ObjIds; return true; } int CBERDecoder::parseComponent(const char* szInputStream, int i, int *piData, int j) { int k = 0; for(int l = 0; l < 4; l++) { k <<= 7; UInt8 byte0 = szInputStream[i++]; k |= byte0 & 0x7f; if((byte0 & 0x80) == 0) { piData[j] = k; return i; } } return -1; } /* int CBERDecoder::decodeExplicit(int nTagNumber) { return decodeConstructed(nTagNumber); } void CBERDecoder::decodeImplicit(int nTagNumber) { if(implicitTag == 0) implicitTag = nTagNumber; } */ //function 0: //universial 0 bool // //function 1 //universial 1 integer // bool CBERDecoder::decodeBCDString(const char* szInputStream, int nLength, String& out) { char *result; int j=0; unsigned char *temp; temp=(unsigned char *)calloc(sizeof(char),nLength); memcpy(temp,szInputStream,nLength); result =new char[2*nLength+1]; for(int i=0;i<nLength;i++) { result[j++]=(int)(temp[i]&0xf)+48; result[j++]=(int)(temp[i]>>4)+48; } if(result[j-1]==(unsigned char)(0xf+48)) result[j-1]=0; else result[j]=0; out=result; free(temp); delete []result; return 1; } bool CBERDecoder::decodeInteger (const char* szInputStream, int nLength, int& out) { int tempvalue=0; unsigned char *temp; temp=(unsigned char *)calloc(sizeof(char),nLength); memcpy(temp,szInputStream,nLength); // //第二个字节长度 //length=temp[1]; printf("[%x]\n",temp[0]); // //标志位为 '1' 各位变反求和加一,再乘 (-1) // if ((temp[0]>>7)==0x1) { // tempvalue+=(int)((temp[2]&0x7f)^0x7f); for(int i=1;i<nLength;i++) { tempvalue=tempvalue*256+(temp[i]^0xff); } tempvalue=(tempvalue+1)*(-1); } //标志位为 '0' 直接求和 else { for(int i=0;i<nLength;i++) { tempvalue=tempvalue*256+(int)temp[i];//;>>4); } } out=tempvalue; return 1; } // 1.分解1、2字节 // 2.按两部分用integer解码指数和尾数。 // 3.符号×尾数×(进制)**指数 -》最终解 /* bool CBERDecoder::decodeIntegerTo(const char* szInputStream, int nLength, String& out) { CBigInt::Decode(szInputStream, nLength, out); return 1; }*/ bool CBERDecoder::decodeIntegerTo(const char* szInputStream, int nLength, String& out) { int tempvalue=0; int HexBase[2]={1,6}; unsigned char HexArray[50]; int DecArray[50];//[2]; int ResultArray[100]; int TempResult[100]; unsigned char temp[100]; int flag=1,flag2=1; int r=0,s=0,t=0; //temp=(unsigned char *)calloc(sizeof(char),nLength); //unsigned char temp[50]; memcpy(temp,szInputStream,nLength); temp[nLength]=0; if (temp[0]==0xff) { // HexArray[r++]=(unsigned short)temp[1]^0xffffffff; for(int i=2;i<nLength;i++) HexArray[r++]=(unsigned short)temp[i]^0xffffffff;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -