Base64解码和QP解码

前段时间在做邮件解码的时候碰到MIME的Base64编码和QP编码

1.Base64编码

  Base64要求把3个8位字节(3*8=24)转化为4个6位的字节(4*6=24),之后在6位的前面补两个0,形成8位一个字节的形式.

  解码算法大概可以分为如下几步几步: 

  读取数据3字节用AND取前6位,放入新的变量中右移两位,高两位清0AND取第一个字节的后2位和第二个字节的前4位移位放入新变量中右移两位,清0……依此类推。

ExpandedBlockStart.gif 代码
//  解码后的长度一般比原文少用占1/4的存储空间,请保证buf有足够的空间
inline  int  Base64Decode( char   *  buf,  const   char   *  base64code,  int  src_len) 
{   
    
if  (src_len  ==   0 )
        src_len 
=  strlen(base64code);

    
int  len  =   0 ;
    unsigned 
char *  psrc  =  (unsigned  char * )base64code;
    
char   *  pbuf  =  buf;
    
int  i ;
    
for  ( i  =   0 ; i  <  src_len  -   4 ; i  +=   4 )
    {
        unsigned 
long  ulTmp  =   * (unsigned  long * )psrc;

        register 
int  b0  =  (GetB64Index(( char )B0(ulTmp))  <<   2   |  GetB64Index(( char )B1(ulTmp))  <<   2   >>   6 &   0xFF ;
        register 
int  b1  =  (GetB64Index(( char )B1(ulTmp))  <<   4   |  GetB64Index(( char )B2(ulTmp))  <<   2   >>   4 &   0xFF ;
        register 
int  b2  =  (GetB64Index(( char )B2(ulTmp))  <<   6   |  GetB64Index(( char )B3(ulTmp))  <<   2   >>   2 &   0xFF ;

 
//        *((unsigned long*)pbuf) = b0 | b1 << 8 | b2 << 16;
         * pbuf ++   =  b0;
        
* pbuf ++   =  b1;
        
* pbuf ++   =  b2;

        psrc  
+=   4
//         pbuf += 4;
        len  +=   3 ;
    }

    
//  处理最后余下的不足4字节的数据
     if  (i  <  src_len)
    {
        
int  rest  =  src_len  -  i;
        unsigned 
long  ulTmp  =   0 ;
        
for  ( int  j  =   0 ; j  <  rest;  ++ j)
        {
            
* (((unsigned  char * ) & ulTmp)  +  j)  =   * psrc ++ ;
        }

        register 
int  b0  =  (GetB64Index(( char )B0(ulTmp))  <<   2   |  GetB64Index(( char )B1(ulTmp))  <<   2   >>   6 &   0xFF ;
        
* pbuf ++   =  b0;
        len  
++ ;

        
if  ( ' = '   !=  B1(ulTmp)  &&   ' = '   !=  B2(ulTmp))
        {
            register 
int  b1  =  (GetB64Index(( char )B1(ulTmp))  <<   4   |  GetB64Index(( char )B2(ulTmp))  <<   2   >>   4 &   0xFF ;
            
* pbuf ++   =  b1;
            len  
++ ;
        }

        
if  ( ' = '   !=  B2(ulTmp)  &&   ' = '   !=  B3(ulTmp))
        {
            register 
int  b2  =  (GetB64Index(( char )B2(ulTmp))  <<   6   |  GetB64Index(( char )B3(ulTmp))  <<   2   >>   2 &   0xFF ;
            
* pbuf ++   =  b2;
            len  
++ ;
        }

    }

    
* pbuf  =   ' \0 '

    
return  len;

 

2.QP(Quote-Printable)编码

   Quoted-Printable编码的基本方法是:输入数据在33-60、62-126范围内的,直接输出;其它的需编码为“=”加两个字节的HEX码(大写)。为保证输出行不超过规定长度,可在行尾加“=\r\n”序列作为软回车。

QP的解码算法: 

ExpandedBlockStart.gif 代码
inline  int  DecodeQuoted(  char *  pDst, const   char *  pSrc,  int  nSrcLen)
{
    
if  (nSrcLen  ==   0 )
        nSrcLen 
=  strlen(pSrc);
    
int  nDstLen;         //  输出的字符计数
     int  i;

    i 
=   0 ;
    nDstLen 
=   0 ;

    
while  (i  <  nSrcLen)
    {
        
if  (strncmp(pSrc,  " =\r\n " 3 ==   0 )         //  软回车,跳过
        {
            pSrc 
+=   3 ;
            i 
+=   3 ;
        }
        
else
        {
            
if  ( * pSrc  ==   ' = ' )         //  是编码字节
            {
                sscanf(pSrc, 
" =%02X " , pDst);
                pDst
++ ;
                pSrc 
+=   3 ;
                i 
+=   3 ;
            }
            
else          //  非编码字节
            {
                
* pDst ++   =  (unsigned  char ) * pSrc ++ ;
                i
++ ;
            }

            nDstLen
++ ;
        }
    }

    
//  输出加个结束符
     * pDst  =   ' \0 ' ;

    
return  nDstLen;
}

 

 

  

转载于:https://www.cnblogs.com/alwaysyouare/archive/2010/01/06/1640496.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值