BASE64学习小记

 Base64编码的思想是是采用64个基本的ASCII码字符对数据进行重新编码。它将需要编码的数据拆分成字节数组。以3个字节为一组。按顺序排列24位数据,再把这24位数据分成4组,即每组6位。再在每组的的最高位前补两个0凑足一个字节。这样就把一个3字节为一组的数据重新编码成了4个字节。当所要编码的数据的字节数不是3的整倍数,也就是说在分组时最后一组不够3个字节。这时在最后一组填充1到2个0字节。并在最后编码完成后在结尾添加1到2个“=”。
例:将对ABC进行BASE64编码
        首先取ABC对应的ASCII码值。A(65)B(66)C(67)。
        再取二进制值A(01000001)B(01000010)C(01000011),然后把这三个字节的二进制码接起来(010000010100001001000011),再以6位为单位分成4个数据块并在最高位填充两个0后形成4个字节的编码后的值(00010000)(00010100)(00001001)(00000011)。蓝色部分为真实数据。再把这四个字节数据转化成10进制数得(16)(20)(19)(3)。

最后根据BASE64给出的64个基本字符表,查出对应的ASCII码字符(Q)(U)(J)(D)。这里的值实际就是数据在字符表中的索引。

  1 const char EnBase64Tab[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345678Array+/";
  2  
  3 int EncodeBase64(const unsigned char* pSrc, char* pDst, int nSrcLen, int nMaxLineLen)
  4 {
  5     unsigned char c1, c2, c3;    // 输入缓冲区读出3个字节
  6     int nDstLen = 0;             // 输出的字符计数
  7     int nLineLen = 0;            // 输出的行长度计数
  8     int nDiv = nSrcLen / 3;      // 输入数据长度除以3得到的倍数
  9     int nMod = nSrcLen % 3;      // 输入数据长度除以3得到的余数
 10  
 11     // 每次取3个字节,编码成4个字符
 12     for (int i = 0; i < nDiv; i ++)
 13     {
 14         // 取3个字节     取24位  3个字节 
 15         // 取3个字节     取24位  3个字节 
 16         c1 = *pSrc++;
 17         c2 = *pSrc++;
 18         c3 = *pSrc++;
 19  
 20         // 编码成4个字符
 21         *pDst++ = EnBase64Tab[c1 >> 2];                          //C1右移2位 高位补0 取到母表
 22         *pDst++ = EnBase64Tab[((c1 << 4| (c2 >> 4)) & 0x3f];   //C2左移4位 C2右移4位  取非(保留作用) 与003F 屏蔽高2位
 23         *pDst++ = EnBase64Tab[((c2 << 2| (c3 >> 6)) & 0x3f];   
 24         *pDst++ = EnBase64Tab[c3 & 0x3f];
 25         nLineLen += 4;
 26         nDstLen += 4;
 27  
 28         // 输出换行?
 29         if (nLineLen > nMaxLineLen - 4)  //结束
 30         {
 31             *pDst++ = ’r’;
 32             *pDst++ = ’n’;
 33             nLineLen = 0;
 34             nDstLen += 2;
 35         }
 36     }
 37  
 38     // 编码余下的字节
 39     if (nMod == 1)
 40     {
 41         c1 = *pSrc++;
 42         *pDst++ = EnBase64Tab[(c1 & 0xfc>> 2];      // 8位 屏蔽低2位
 43         *pDst++ = EnBase64Tab[((c1 & 0x03<< 4)];    // 保留低2位     
 44         *pDst++ = ’=’;                               // 另外2个字符 用=表示
 45         *pDst++ = ’=’;
 46         nLineLen += 4;
 47         nDstLen += 4;
 48     }
 49     else if (nMod == 2)
 50     {
 51         c1 = *pSrc++;
 52         c2 = *pSrc++;
 53         *pDst++ = EnBase64Tab[(c1 & 0xfc>> 2];                       
 54 
 55         *pDst++ = EnBase64Tab[((c1 & 0x03<< 4| ((c2 & 0xf0>> 4)];
 56         *pDst++ = EnBase64Tab[((c2 & 0x0f<< 2)];
 57         *pDst++ = ’=’;
 58         nDstLen += 4;
 59     }
 60  
 61     // 输出加个结束符
 62     *pDst = ’’;
 63  
 64     return nDstLen;
 65 }
 66 Base64解码方法中,最简单的也是查表法:将64个可打印字符的值作为索引,查表得到的值(范围为0-63)依次连起来,拼凑成字节形式输出,就得到解码结果。 
 67 
 68 const char DeBase64Tab[] =
 69 {
 70     000000000000000000000000,
 71     0000000000000000000,
 72     62,        // ’+’
 73     000,
 74     63,        // ’/’
 75     52535455565758, 5Array, 6061,        // ’0’-’Array’
 76     0000000,
 77     012345678, Array, 101112,
 78     131415161718, 1Array, 202122232425,        // ’A’-’Z’
 79     000000,
 80     262728, 2Array, 303132333435363738,
 81     3Array, 404142434445464748, 4Array, 5051,        // ’a’-’z’
 82 };
 83  
 84 
 85 
 86 void DEbase644(char * string  ,char * pch)   
 87 {   
 88   
 89     int len = str.GetLength();   
 90   
 91     int i = 0;   
 92     BYTE b1 ,b2 ,b3 ,b4;   
 93     char ch;   
 94     do  
 95     {   
 96         //找字符1的位置.   
 97         b1 = tab.Find((str[i++]));   
 98   
 99         //找字符2的位置.   
100         b2 = tab.Find((str[i++]));   
101    
102         ch = (b1 << 2+ (b2 >> 4);     //B1 高2位清空 低2位与B2右移后 末4位相与 得到后2位 相与得到第一个字符;
103         //得到此字节..   
104         *pch ++ = ch;   
105         
106         if(i >= len)     //超过了..break吧..这是要有这个=号...当=成立的时候.表明已经是最后一个字符了...后面不要处理.. 
107         break;   
108         
109         b3 = tab.Find((str[i++]));    //取第3个字符..的位置  
110   
111         //从这里开始判断..因为=号最多有两个...换行是额外加的..所以编码后有效的字符至少为2个..   
112   
113   
114         ch = (b2 <<4+ (b3 >> 2);        //B2左移4 清理 补0和B1的尾巴    数数数数 空空空空   B3右移2  空空空空数数数数  相与 得到第二个字符
115                                                                                                            补零
116         *pch ++ = ch;     
117         if(i >= len)     //超过了..break吧. 
118          break;          
119         b4 = tab.Find((str[i++]));   //找第4个字符..  
120         ch = (b3 << 6+ b4;   // B3右移6 得到第三个字符的高2位 与上  B4  空空 数数数数数数 得到 第三个字符 
121   
122         *pch ++ = ch;   
123   
124     }   
125     while(i < len);   
126     ////最后加个结束符...   
127     *pch =0x00;   
128 }  
posted @ 2011-07-14 14:14  XH_3  阅读(337)  评论(0编辑  收藏  举报