Base64編、解碼原理,及代碼實現(二)

//------------------------------------分割線--------------------------------------------//
解碼代碼:
string Base64Decode(const string &s)//s形參是編碼後的字符串
{
int lenString = s.length();
string StrSource = s;
//表中的數值是表示在Base64表中的值,也就是6位2進制數的10進制的值!
const int dekey[]={
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
62, // '+'
-1, -1, -1,
63, // '-'
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // '0'-'9'
-1, -1, -1, -1, -1, -1, -1,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // 'A'-'Z'
-1, -1, -1, -1, -1, -1,
26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // 'a'-'z'
};




if(lenString % 4 != 0)
throw "Bad Base64 string";


int nLoop = (StrSource[lenString-1]=='=') ? lenString-4:lenString;
//不論傳進來的形參最後有一個還是兩個"=",都要少進行一個循環,所以以最後一個"="爲準;


string DecodeStr(lenString*3/4+4,'\0');
int b[4]={0};
int i=0,n=0;
//cout<<dekey[static_cast<int>(StrSource[1])]<<endl;
for(i=0;i<nLoop;i+=4)
{
//其實,這裏的StrSource[i]雖然是字符型,不過它通過隱性轉換由char類型->int類型
//char類型->2進制->10進制int類型
b[0]=dekey[StrSource[i]];
b[1]=dekey[StrSource[i+1]];
b[2]=dekey[StrSource[i+2]];
b[3]=dekey[StrSource[i+3]];




if(b[0] == -1 || b[1] == -1 || b[2] == -1 || b[3] == -1)
             throw "bad base64 string";


DecodeStr[n]=((b[0] & 0x3f)<<2)|((b[1] & 0x30)>>4);
DecodeStr[n+1]=((b[1] & 0x0f)<<4)|((b[2] & 0x3c)>>2);
DecodeStr[n+2]=((b[2] & 0x03)<<6)|((b[3] &0x3f));


n+=3;
}


if(StrSource[lenString-1]=='=' && StrSource[lenString-2]=='=')
{
b[0]=dekey[StrSource[i]];
b[1]=dekey[StrSource[i+1]];




if(b[0] == -1 || b[1] == -1)
             throw "bad base64 string";




DecodeStr[n]=((b[0] & 0x3f)<<2)|((b[1]&0x30)>>4);
DecodeStr[n+1]='\0';
}
if(StrSource[lenString-1]=='=' && StrSource[lenString-2]!='=')
{
b[0]=dekey[StrSource[i]];
b[1]=dekey[StrSource[i+1]];
b[2]=dekey[StrSource[i+2]];




if(b[0] == -1 || b[1] == -1 || b[2]== -1)
             throw "bad base64 string";


DecodeStr[n]=((b[0] & 0x3f)<<2)|((b[1]&0x30)>>4);
DecodeStr[n+1]=((b[1]&0xf)<<4)|((b[2]&0x3c)>>2);
DecodeStr[n+2]='\0';
}
if( StrSource[lenString-1] != '=' && StrSource[lenString-2] != '=' )
         DecodeStr[n] = '\0';




//這裏返回string類型的C風格字符串,這樣可以將string類型變量多餘的'\0'除去
return DecodeStr.c_str();
};

3.解碼中的位運算(編碼的位運算同理)

  其中對於6位2進制轉8位2進制的過程,例如:DecodeStr[n]=((b[0] & 0x3f)<<2)|((b[1]&0x30)>>4)。由於b[0]是一個6位2進制數,比如是110011=51,變成8位2進制數的話是00110011,那麼經過b[0] & 0x3f 得到6位的後6位,然後向左移位2,就變成了11001100,同理b[1]&0x30也是一樣,比如b[1]=00100001=33,因爲b[0]是6位有效,那麼就要求b[1]的前2位要與b[0]的6位結合變成8位2進制數,過程如下:
  b[0] & 0x3 == 00110011,b[1] & 0x30 == 00100000,然後通過位運算,b[0]左移6位,b[1]右移4,再由或運算得到:11001100 | 00000010 = 11001110,這就是最後的8位2進制數,算出它的值然後使得char類型變量等於此2進制數,計算機通過查表,得到了該2進制數所對應的字符。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章