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       0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ,
 71       0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ,
 72       62 ,         //  ’+’
 73       0 0 0 ,
 74       63 ,         //  ’/’
 75       52 53 54 55 56 57 58 , 5Array,  60 61 ,         //  ’0’-’Array’
 76       0 0 0 0 0 0 0 ,
 77       0 1 2 3 4 5 6 7 8 , Array,  10 11 12 ,
 78       13 14 15 16 17 18 , 1Array,  20 21 22 23 24 25 ,         //  ’A’-’Z’
 79       0 0 0 0 0 0 ,
 80       26 27 28 , 2Array,  30 31 32 33 34 35 36 37 38 ,
 81      3Array,  40 41 42 43 44 45 46 47 48 , 4Array,  50 51 ,         //  ’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  }  

转载于:https://www.cnblogs.com/lch03/archive/2011/07/14/2106311.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值